From 13c7f8f24450f520e4021336753c5a9219d52cf6 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 09:12:58 -0800 Subject: [PATCH 01/13] docs: [google-cloud-batch] Remove UUID specification in comment (#12366) - [ ] Regenerate this pull request now. PiperOrigin-RevId: 610659360 Source-Link: https://github.com/googleapis/googleapis/commit/a17ce769d068601f2293cb34a58d7c26e382fa99 Source-Link: https://github.com/googleapis/googleapis-gen/commit/ac0d5d8cce099ed4c66e74309c44bac30afcf3a3 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLWJhdGNoLy5Pd2xCb3QueWFtbCIsImgiOiJhYzBkNWQ4Y2NlMDk5ZWQ0YzY2ZTc0MzA5YzQ0YmFjMzBhZmNmM2EzIn0= BEGIN_NESTED_COMMIT docs: [google-cloud-batch] update description of Job uid field PiperOrigin-RevId: 610543580 Source-Link: https://github.com/googleapis/googleapis/commit/f6b39e27a6aa34f30feede55b3c69f00d7279076 Source-Link: https://github.com/googleapis/googleapis-gen/commit/dbfb1cca5719c074422eb2358ed193bfd9f4a218 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLWJhdGNoLy5Pd2xCb3QueWFtbCIsImgiOiJkYmZiMWNjYTU3MTljMDc0NDIyZWIyMzU4ZWQxOTNiZmQ5ZjRhMjE4In0= END_NESTED_COMMIT --------- Co-authored-by: Owl Bot --- .../google-cloud-batch/google/cloud/batch/gapic_version.py | 2 +- .../google-cloud-batch/google/cloud/batch_v1/gapic_version.py | 2 +- .../google-cloud-batch/google/cloud/batch_v1/types/job.py | 4 ++-- .../google/cloud/batch_v1alpha/gapic_version.py | 2 +- .../google/cloud/batch_v1alpha/types/job.py | 4 ++-- .../snippet_metadata_google.cloud.batch.v1.json | 2 +- .../snippet_metadata_google.cloud.batch.v1alpha.json | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/google-cloud-batch/google/cloud/batch/gapic_version.py b/packages/google-cloud-batch/google/cloud/batch/gapic_version.py index 7f67df2cb9c1..360a0d13ebdd 100644 --- a/packages/google-cloud-batch/google/cloud/batch/gapic_version.py +++ b/packages/google-cloud-batch/google/cloud/batch/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.17.12" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-batch/google/cloud/batch_v1/gapic_version.py b/packages/google-cloud-batch/google/cloud/batch_v1/gapic_version.py index 7f67df2cb9c1..360a0d13ebdd 100644 --- a/packages/google-cloud-batch/google/cloud/batch_v1/gapic_version.py +++ b/packages/google-cloud-batch/google/cloud/batch_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.17.12" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-batch/google/cloud/batch_v1/types/job.py b/packages/google-cloud-batch/google/cloud/batch_v1/types/job.py index 92d35f6d23b0..dbf3dc34903e 100644 --- a/packages/google-cloud-batch/google/cloud/batch_v1/types/job.py +++ b/packages/google-cloud-batch/google/cloud/batch_v1/types/job.py @@ -46,8 +46,8 @@ class Job(proto.Message): For example: "projects/123456/locations/us-central1/jobs/job01". uid (str): - Output only. A system generated unique ID (in - UUID4 format) for the Job. + Output only. A system generated unique ID for + the Job. priority (int): Priority of the Job. The valid value range is [0, 100). Default value is 0. Higher value indicates higher priority. diff --git a/packages/google-cloud-batch/google/cloud/batch_v1alpha/gapic_version.py b/packages/google-cloud-batch/google/cloud/batch_v1alpha/gapic_version.py index 7f67df2cb9c1..360a0d13ebdd 100644 --- a/packages/google-cloud-batch/google/cloud/batch_v1alpha/gapic_version.py +++ b/packages/google-cloud-batch/google/cloud/batch_v1alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.17.12" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-batch/google/cloud/batch_v1alpha/types/job.py b/packages/google-cloud-batch/google/cloud/batch_v1alpha/types/job.py index e5281086e4b7..2d99b8e88adc 100644 --- a/packages/google-cloud-batch/google/cloud/batch_v1alpha/types/job.py +++ b/packages/google-cloud-batch/google/cloud/batch_v1alpha/types/job.py @@ -48,8 +48,8 @@ class Job(proto.Message): For example: "projects/123456/locations/us-central1/jobs/job01". uid (str): - Output only. A system generated unique ID (in - UUID4 format) for the Job. + Output only. A system generated unique ID for + the Job. priority (int): Priority of the Job. The valid value range is [0, 100). Default value is 0. Higher value indicates higher priority. diff --git a/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1.json b/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1.json index 0c9222258cd9..e2df1067e4dd 100644 --- a/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1.json +++ b/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-batch", - "version": "0.17.12" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1alpha.json b/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1alpha.json index 4d667a570409..4862cc9a6486 100644 --- a/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1alpha.json +++ b/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-batch", - "version": "0.17.12" + "version": "0.1.0" }, "snippets": [ { From 394a05fe2b3d2582c4f161efc574fe8e1625c913 Mon Sep 17 00:00:00 2001 From: "owlbot-bootstrapper[bot]" <104649659+owlbot-bootstrapper[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 13:10:18 -0500 Subject: [PATCH 02/13] feat: add initial files for google.apps.card.v1 (#12370) Source-Link: https://github.com/googleapis/googleapis-gen/commit/c8819889b543243eedf81b9d327bed4cce46647e Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWFwcHMtY2FyZC8uT3dsQm90LnlhbWwiLCJoIjoiYzg4MTk4ODliNTQzMjQzZWVkZjgxYjlkMzI3YmVkNGNjZTQ2NjQ3ZSJ9 PiperOrigin-RevId: 609795940 --------- Co-authored-by: Owlbot Bootstrapper Co-authored-by: Owl Bot Co-authored-by: Anthonios Partheniou --- packages/google-apps-card/.OwlBot.yaml | 18 + packages/google-apps-card/.coveragerc | 13 + packages/google-apps-card/.flake8 | 33 + packages/google-apps-card/.gitignore | 63 + packages/google-apps-card/.repo-metadata.json | 17 + packages/google-apps-card/CHANGELOG.md | 1 + packages/google-apps-card/CODE_OF_CONDUCT.md | 95 + packages/google-apps-card/CONTRIBUTING.rst | 271 ++ packages/google-apps-card/LICENSE | 202 ++ packages/google-apps-card/MANIFEST.in | 25 + packages/google-apps-card/README.rst | 108 + packages/google-apps-card/docs/CHANGELOG.md | 1 + packages/google-apps-card/docs/README.rst | 1 + .../google-apps-card/docs/_static/custom.css | 20 + .../docs/_templates/layout.html | 50 + .../docs/card_v1/services_.rst | 4 + .../google-apps-card/docs/card_v1/types_.rst | 6 + packages/google-apps-card/docs/conf.py | 384 +++ packages/google-apps-card/docs/index.rst | 23 + .../google-apps-card/docs/multiprocessing.rst | 7 + .../google/apps/card/__init__.py | 67 + .../google/apps/card/gapic_version.py | 16 + .../google/apps/card/py.typed | 2 + .../google/apps/card_v1/__init__.py | 67 + .../google/apps/card_v1/gapic_metadata.json | 7 + .../google/apps/card_v1/gapic_version.py | 16 + .../google/apps/card_v1/py.typed | 2 + .../google/apps/card_v1/services/__init__.py | 15 + .../google/apps/card_v1/types/__init__.py | 62 + .../google/apps/card_v1/types/card.py | 2886 +++++++++++++++++ packages/google-apps-card/mypy.ini | 3 + packages/google-apps-card/noxfile.py | 428 +++ .../scripts/decrypt-secrets.sh | 46 + .../scripts/fixup_card_v1_keywords.py | 175 + packages/google-apps-card/setup.py | 91 + packages/google-apps-card/testing/.gitignore | 3 + .../testing/constraints-3.10.txt | 6 + .../testing/constraints-3.11.txt | 6 + .../testing/constraints-3.12.txt | 6 + .../testing/constraints-3.7.txt | 10 + .../testing/constraints-3.8.txt | 6 + .../testing/constraints-3.9.txt | 6 + packages/google-apps-card/tests/__init__.py | 15 + .../google-apps-card/tests/unit/__init__.py | 15 + .../tests/unit/gapic/__init__.py | 15 + .../tests/unit/gapic/card_v1/__init__.py | 15 + .../tests/unit/gapic/card_v1/test_card.py | 23 + 47 files changed, 5351 insertions(+) create mode 100644 packages/google-apps-card/.OwlBot.yaml create mode 100644 packages/google-apps-card/.coveragerc create mode 100644 packages/google-apps-card/.flake8 create mode 100644 packages/google-apps-card/.gitignore create mode 100644 packages/google-apps-card/.repo-metadata.json create mode 100644 packages/google-apps-card/CHANGELOG.md create mode 100644 packages/google-apps-card/CODE_OF_CONDUCT.md create mode 100644 packages/google-apps-card/CONTRIBUTING.rst create mode 100644 packages/google-apps-card/LICENSE create mode 100644 packages/google-apps-card/MANIFEST.in create mode 100644 packages/google-apps-card/README.rst create mode 120000 packages/google-apps-card/docs/CHANGELOG.md create mode 120000 packages/google-apps-card/docs/README.rst create mode 100644 packages/google-apps-card/docs/_static/custom.css create mode 100644 packages/google-apps-card/docs/_templates/layout.html create mode 100644 packages/google-apps-card/docs/card_v1/services_.rst create mode 100644 packages/google-apps-card/docs/card_v1/types_.rst create mode 100644 packages/google-apps-card/docs/conf.py create mode 100644 packages/google-apps-card/docs/index.rst create mode 100644 packages/google-apps-card/docs/multiprocessing.rst create mode 100644 packages/google-apps-card/google/apps/card/__init__.py create mode 100644 packages/google-apps-card/google/apps/card/gapic_version.py create mode 100644 packages/google-apps-card/google/apps/card/py.typed create mode 100644 packages/google-apps-card/google/apps/card_v1/__init__.py create mode 100644 packages/google-apps-card/google/apps/card_v1/gapic_metadata.json create mode 100644 packages/google-apps-card/google/apps/card_v1/gapic_version.py create mode 100644 packages/google-apps-card/google/apps/card_v1/py.typed create mode 100644 packages/google-apps-card/google/apps/card_v1/services/__init__.py create mode 100644 packages/google-apps-card/google/apps/card_v1/types/__init__.py create mode 100644 packages/google-apps-card/google/apps/card_v1/types/card.py create mode 100644 packages/google-apps-card/mypy.ini create mode 100644 packages/google-apps-card/noxfile.py create mode 100755 packages/google-apps-card/scripts/decrypt-secrets.sh create mode 100644 packages/google-apps-card/scripts/fixup_card_v1_keywords.py create mode 100644 packages/google-apps-card/setup.py create mode 100644 packages/google-apps-card/testing/.gitignore create mode 100644 packages/google-apps-card/testing/constraints-3.10.txt create mode 100644 packages/google-apps-card/testing/constraints-3.11.txt create mode 100644 packages/google-apps-card/testing/constraints-3.12.txt create mode 100644 packages/google-apps-card/testing/constraints-3.7.txt create mode 100644 packages/google-apps-card/testing/constraints-3.8.txt create mode 100644 packages/google-apps-card/testing/constraints-3.9.txt create mode 100644 packages/google-apps-card/tests/__init__.py create mode 100644 packages/google-apps-card/tests/unit/__init__.py create mode 100644 packages/google-apps-card/tests/unit/gapic/__init__.py create mode 100644 packages/google-apps-card/tests/unit/gapic/card_v1/__init__.py create mode 100644 packages/google-apps-card/tests/unit/gapic/card_v1/test_card.py diff --git a/packages/google-apps-card/.OwlBot.yaml b/packages/google-apps-card/.OwlBot.yaml new file mode 100644 index 000000000000..5d11a56a79d7 --- /dev/null +++ b/packages/google-apps-card/.OwlBot.yaml @@ -0,0 +1,18 @@ +# Copyright 2022 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. + +deep-copy-regex: + - source: /google/apps/card/(v.*)/.*-py + dest: /owl-bot-staging/google-apps-card/$1 +api-name: google-apps-card diff --git a/packages/google-apps-card/.coveragerc b/packages/google-apps-card/.coveragerc new file mode 100644 index 000000000000..4d0a316cdc27 --- /dev/null +++ b/packages/google-apps-card/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/apps/card/__init__.py + google/apps/card/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/packages/google-apps-card/.flake8 b/packages/google-apps-card/.flake8 new file mode 100644 index 000000000000..87f6e408c47d --- /dev/null +++ b/packages/google-apps-card/.flake8 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2023 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. + +# Generated by synthtool. DO NOT EDIT! +[flake8] +ignore = E203, E231, E266, E501, W503 +exclude = + # Exclude generated code. + **/proto/** + **/gapic/** + **/services/** + **/types/** + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/packages/google-apps-card/.gitignore b/packages/google-apps-card/.gitignore new file mode 100644 index 000000000000..b4243ced74e4 --- /dev/null +++ b/packages/google-apps-card/.gitignore @@ -0,0 +1,63 @@ +*.py[cod] +*.sw[op] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +.eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 +__pycache__ + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.nox +.cache +.pytest_cache + + +# Mac +.DS_Store + +# JetBrains +.idea + +# VS Code +.vscode + +# emacs +*~ + +# Built documentation +docs/_build +bigquery/docs/generated +docs.metadata + +# Virtual environment +env/ + +# Test logs +coverage.xml +*sponge_log.xml + +# System test environment variables. +system_tests/local_test_setup + +# Make sure a generated file isn't accidentally committed. +pylintrc +pylintrc.test diff --git a/packages/google-apps-card/.repo-metadata.json b/packages/google-apps-card/.repo-metadata.json new file mode 100644 index 000000000000..52344458c237 --- /dev/null +++ b/packages/google-apps-card/.repo-metadata.json @@ -0,0 +1,17 @@ +{ + "name": "google-apps-card", + "name_pretty": "Google Apps Card Protos", + "api_description": "Google Apps Card Protos", + "product_documentation": "https://developers.google.com/chat", + "client_documentation": "https://googleapis.dev/python/google-apps-card/latest", + "issue_tracker": "https://github.com/googleapis/google-cloud-python/issues", + "release_level": "preview", + "language": "python", + "library_type": "GAPIC_AUTO", + "repo": "googleapis/google-cloud-python", + "distribution_name": "google-apps-card", + "api_id": "card.googleapis.com", + "default_version": "v1", + "codeowner_team": "", + "api_shortname": "card" +} diff --git a/packages/google-apps-card/CHANGELOG.md b/packages/google-apps-card/CHANGELOG.md new file mode 100644 index 000000000000..5ddad421e08f --- /dev/null +++ b/packages/google-apps-card/CHANGELOG.md @@ -0,0 +1 @@ +# Changelog \ No newline at end of file diff --git a/packages/google-apps-card/CODE_OF_CONDUCT.md b/packages/google-apps-card/CODE_OF_CONDUCT.md new file mode 100644 index 000000000000..039f43681204 --- /dev/null +++ b/packages/google-apps-card/CODE_OF_CONDUCT.md @@ -0,0 +1,95 @@ + +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +This Code of Conduct also applies outside the project spaces when the Project +Steward has a reasonable belief that an individual's behavior may have a +negative impact on the project or its community. + +## Conflict Resolution + +We do not believe that all conflict is bad; healthy debate and disagreement +often yield positive results. However, it is never okay to be disrespectful or +to engage in behavior that violates the project’s code of conduct. + +If you see someone violating the code of conduct, you are encouraged to address +the behavior directly with those involved. Many issues can be resolved quickly +and easily, and this gives people more control over the outcome of their +dispute. If you are unable to resolve the matter for any reason, or if the +behavior is threatening or harassing, report it. We are dedicated to providing +an environment where participants feel welcome and safe. + + +Reports should be directed to *googleapis-stewards@google.com*, the +Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to +receive and address reported violations of the code of conduct. They will then +work with a committee consisting of representatives from the Open Source +Programs Office and the Google Open Source Strategy team. If for any reason you +are uncomfortable reaching out to the Project Steward, please email +opensource@google.com. + +We will investigate every complaint, but you may not receive a direct response. +We will use our discretion in determining when and how to follow up on reported +incidents, which may range from not taking action to permanent expulsion from +the project and project-sponsored spaces. We will notify the accused of the +report and provide them an opportunity to discuss it before any action is taken. +The identity of the reporter will be omitted from the details of the report +supplied to the accused. In potentially harmful situations, such as ongoing +harassment or threats to anyone's safety, we may take action without notice. + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at +https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/packages/google-apps-card/CONTRIBUTING.rst b/packages/google-apps-card/CONTRIBUTING.rst new file mode 100644 index 000000000000..f21262ffe7ad --- /dev/null +++ b/packages/google-apps-card/CONTRIBUTING.rst @@ -0,0 +1,271 @@ +.. Generated by synthtool. DO NOT EDIT! +############ +Contributing +############ + +#. **Please sign one of the contributor license agreements below.** +#. Fork the repo, develop and test your code changes, add docs. +#. Make sure that your commit messages clearly describe the changes. +#. Send a pull request. (Please Read: `Faster Pull Request Reviews`_) + +.. _Faster Pull Request Reviews: https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#best-practices-for-faster-reviews + +.. contents:: Here are some guidelines for hacking on the Google Cloud Client libraries. + +*************** +Adding Features +*************** + +In order to add a feature: + +- The feature must be documented in both the API and narrative + documentation. + +- The feature must work fully on the following CPython versions: + 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 on both UNIX and Windows. + +- The feature must not add unnecessary dependencies (where + "unnecessary" is of course subjective, but new dependencies should + be discussed). + +**************************** +Using a Development Checkout +**************************** + +You'll have to create a development environment using a Git checkout: + +- While logged into your GitHub account, navigate to the + ``google-cloud-python`` `repo`_ on GitHub. + +- Fork and clone the ``google-cloud-python`` repository to your GitHub account by + clicking the "Fork" button. + +- Clone your fork of ``google-cloud-python`` from your GitHub account to your local + computer, substituting your account username and specifying the destination + as ``hack-on-google-cloud-python``. E.g.:: + + $ cd ${HOME} + $ git clone git@github.com:USERNAME/google-cloud-python.git hack-on-google-cloud-python + $ cd hack-on-google-cloud-python + # Configure remotes such that you can pull changes from the googleapis/google-cloud-python + # repository into your local repository. + $ git remote add upstream git@github.com:googleapis/google-cloud-python.git + # fetch and merge changes from upstream into main + $ git fetch upstream + $ git merge upstream/main + +Now your local repo is set up such that you will push changes to your GitHub +repo, from which you can submit a pull request. + +To work on the codebase and run the tests, we recommend using ``nox``, +but you can also use a ``virtualenv`` of your own creation. + +.. _repo: https://github.com/googleapis/google-cloud-python + +Using ``nox`` +============= + +We use `nox `__ to instrument our tests. + +- To test your changes, run unit tests with ``nox``:: + $ nox -s unit + +- To run a single unit test:: + + $ nox -s unit-3.12 -- -k + + + .. note:: + + The unit tests and system tests are described in the + ``noxfile.py`` files in each directory. + +.. nox: https://pypi.org/project/nox/ + +***************************************** +I'm getting weird errors... Can you help? +***************************************** + +If the error mentions ``Python.h`` not being found, +install ``python-dev`` and try again. +On Debian/Ubuntu:: + + $ sudo apt-get install python-dev + +************ +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 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:: + + $ nox -s lint + +- In order to make ``nox -s lint`` run faster, you can set some environment + variables:: + + export GOOGLE_CLOUD_TESTING_REMOTE="upstream" + export GOOGLE_CLOUD_TESTING_BRANCH="main" + + By doing this, you are specifying the location of the most up-to-date + version of ``google-cloud-python``. The + remote name ``upstream`` should point to the official ``googleapis`` + checkout and the branch should be the default branch on that remote (``main``). + +- This repository contains configuration for the + `pre-commit `__ tool, which automates checking + our linters during a commit. If you have it installed on your ``$PATH``, + you can enable enforcing those checks via: + +.. code-block:: bash + + $ pre-commit install + pre-commit installed at .git/hooks/pre-commit + +Exceptions to PEP8: + +- Many unit tests use a helper method, ``_call_fut`` ("FUT" is short for + "Function-Under-Test"), which is PEP8-incompliant, but more readable. + Some also use a local variable, ``MUT`` (short for "Module-Under-Test"). + +******************** +Running System Tests +******************** + +- To run system tests, you can execute:: + + # Run all system tests + $ nox -s system + + # Run a single system test + $ nox -s system-3.12 -- -k + + + .. note:: + + System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11 and 3.12. + 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 + auth settings and change some configuration in your project to + run all the tests. + +- System tests will be run against an actual project. You should use local credentials from gcloud when possible. See `Best practices for application authentication `__. Some tests require a service account. For those tests see `Authenticating as a service account `__. + +************* +Test Coverage +************* + +- The codebase *must* have 100% test statement coverage after each commit. + You can test coverage via ``nox -s cover``. + +****************************************************** +Documentation Coverage and Building HTML Documentation +****************************************************** + +If you fix a bug, and the bug requires an API or behavior modification, all +documentation in this package which references that API or behavior must be +changed to reflect the bug fix, ideally in the same commit that fixes the bug +or adds the feature. + +Build the docs via: + + $ nox -s docs + +************************* +Samples and code snippets +************************* + +Code samples and snippets live in the `samples/` catalogue. Feel free to +provide more examples, but make sure to write tests for those examples. +Each folder containing example code requires its own `noxfile.py` script +which automates testing. If you decide to create a new folder, you can +base it on the `samples/snippets` folder (providing `noxfile.py` and +the requirements files). + +The tests will run against a real Google Cloud Project, so you should +configure them just like the System Tests. + +- To run sample tests, you can execute:: + + # Run all tests in a folder + $ cd samples/snippets + $ nox -s py-3.8 + + # Run a single sample test + $ cd samples/snippets + $ nox -s py-3.8 -- -k + +******************************************** +Note About ``README`` as it pertains to PyPI +******************************************** + +The `description on PyPI`_ for the project comes directly from the +``README``. Due to the reStructuredText (``rst``) parser used by +PyPI, relative links which will work on GitHub (e.g. ``CONTRIBUTING.rst`` +instead of +``https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst``) +may cause problems creating links or rendering the description. + +.. _description on PyPI: https://pypi.org/project/google-apps-card + + +************************* +Supported Python Versions +************************* + +We support: + +- `Python 3.7`_ +- `Python 3.8`_ +- `Python 3.9`_ +- `Python 3.10`_ +- `Python 3.11`_ +- `Python 3.12`_ + +.. _Python 3.7: https://docs.python.org/3.7/ +.. _Python 3.8: https://docs.python.org/3.8/ +.. _Python 3.9: https://docs.python.org/3.9/ +.. _Python 3.10: https://docs.python.org/3.10/ +.. _Python 3.11: https://docs.python.org/3.11/ +.. _Python 3.12: https://docs.python.org/3.12/ + + +Supported versions can be found in our ``noxfile.py`` `config`_. + +.. _config: https://github.com/googleapis/google-cloud-python/blob/main/packages/google-apps-card/noxfile.py + + +********** +Versioning +********** + +This library follows `Semantic Versioning`_. + +.. _Semantic Versioning: http://semver.org/ + +Some packages are currently in major version zero (``0.y.z``), which means that +anything may change at any time and the public API should not be considered +stable. + +****************************** +Contributor License Agreements +****************************** + +Before we can accept your pull requests you'll need to sign a Contributor +License Agreement (CLA): + +- **If you are an individual writing original source code** and **you own the + intellectual property**, then you'll need to sign an + `individual CLA `__. +- **If you work for a company that wants to allow you to contribute your work**, + then you'll need to sign a + `corporate CLA `__. + +You can sign these electronically (just scroll to the bottom). After that, +we'll be able to accept your pull requests. diff --git a/packages/google-apps-card/LICENSE b/packages/google-apps-card/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/packages/google-apps-card/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/packages/google-apps-card/MANIFEST.in b/packages/google-apps-card/MANIFEST.in new file mode 100644 index 000000000000..e0a66705318e --- /dev/null +++ b/packages/google-apps-card/MANIFEST.in @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2023 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. + +# Generated by synthtool. DO NOT EDIT! +include README.rst LICENSE +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 diff --git a/packages/google-apps-card/README.rst b/packages/google-apps-card/README.rst new file mode 100644 index 000000000000..0d97915d9035 --- /dev/null +++ b/packages/google-apps-card/README.rst @@ -0,0 +1,108 @@ +Python Client for Google Apps Card Protos +========================================= + +|preview| |pypi| |versions| + +`Google Apps Card Protos`_: Google Apps Card Protos + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-apps-card.svg + :target: https://pypi.org/project/google-apps-card/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-apps-card.svg + :target: https://pypi.org/project/google-apps-card/ +.. _Google Apps Card Protos: https://developers.google.com/chat +.. _Client Library Documentation: https://googleapis.dev/python/google-apps-card/latest +.. _Product Documentation: https://developers.google.com/chat + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. `Enable the Google Apps Card Protos.`_ +4. `Setup Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Enable the Google Apps Card Protos.: https://developers.google.com/chat +.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-card/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.7 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.6 + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-apps-card + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-apps-card + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Google Apps Card Protos + to see other available methods on the client. +- Read the `Google Apps Card Protos Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Google Apps Card Protos Product documentation: https://developers.google.com/chat +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst diff --git a/packages/google-apps-card/docs/CHANGELOG.md b/packages/google-apps-card/docs/CHANGELOG.md new file mode 120000 index 000000000000..04c99a55caae --- /dev/null +++ b/packages/google-apps-card/docs/CHANGELOG.md @@ -0,0 +1 @@ +../CHANGELOG.md \ No newline at end of file diff --git a/packages/google-apps-card/docs/README.rst b/packages/google-apps-card/docs/README.rst new file mode 120000 index 000000000000..89a0106941ff --- /dev/null +++ b/packages/google-apps-card/docs/README.rst @@ -0,0 +1 @@ +../README.rst \ No newline at end of file diff --git a/packages/google-apps-card/docs/_static/custom.css b/packages/google-apps-card/docs/_static/custom.css new file mode 100644 index 000000000000..b0a295464b23 --- /dev/null +++ b/packages/google-apps-card/docs/_static/custom.css @@ -0,0 +1,20 @@ +div#python2-eol { + border-color: red; + border-width: medium; +} + +/* Ensure minimum width for 'Parameters' / 'Returns' column */ +dl.field-list > dt { + min-width: 100px +} + +/* Insert space between methods for readability */ +dl.method { + padding-top: 10px; + padding-bottom: 10px +} + +/* Insert empty space between classes */ +dl.class { + padding-bottom: 50px +} diff --git a/packages/google-apps-card/docs/_templates/layout.html b/packages/google-apps-card/docs/_templates/layout.html new file mode 100644 index 000000000000..6316a537f72b --- /dev/null +++ b/packages/google-apps-card/docs/_templates/layout.html @@ -0,0 +1,50 @@ + +{% extends "!layout.html" %} +{%- block content %} +{%- if theme_fixed_sidebar|lower == 'true' %} +
+ {{ sidebar() }} + {%- block document %} +
+ {%- if render_sidebar %} +
+ {%- endif %} + + {%- block relbar_top %} + {%- if theme_show_relbar_top|tobool %} + + {%- endif %} + {% endblock %} + +
+
+ As of January 1, 2020 this library no longer supports Python 2 on the latest released version. + Library versions released prior to that date will continue to be available. For more information please + visit Python 2 support on Google Cloud. +
+ {% block body %} {% endblock %} +
+ + {%- block relbar_bottom %} + {%- if theme_show_relbar_bottom|tobool %} + + {%- endif %} + {% endblock %} + + {%- if render_sidebar %} +
+ {%- endif %} +
+ {%- endblock %} +
+
+{%- else %} +{{ super() }} +{%- endif %} +{%- endblock %} diff --git a/packages/google-apps-card/docs/card_v1/services_.rst b/packages/google-apps-card/docs/card_v1/services_.rst new file mode 100644 index 000000000000..582c850104f3 --- /dev/null +++ b/packages/google-apps-card/docs/card_v1/services_.rst @@ -0,0 +1,4 @@ +Services for Google Apps Card v1 API +==================================== +.. toctree:: + :maxdepth: 2 diff --git a/packages/google-apps-card/docs/card_v1/types_.rst b/packages/google-apps-card/docs/card_v1/types_.rst new file mode 100644 index 000000000000..ed5e6dc5e6d0 --- /dev/null +++ b/packages/google-apps-card/docs/card_v1/types_.rst @@ -0,0 +1,6 @@ +Types for Google Apps Card v1 API +================================= + +.. automodule:: google.apps.card_v1.types + :members: + :show-inheritance: diff --git a/packages/google-apps-card/docs/conf.py b/packages/google-apps-card/docs/conf.py new file mode 100644 index 000000000000..bb4463d27528 --- /dev/null +++ b/packages/google-apps-card/docs/conf.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# google-apps-card documentation build configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import os +import shlex +import sys + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath("..")) + +# For plugins that can not read conf.py. +# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85 +sys.path.insert(0, os.path.abspath(".")) + +__version__ = "" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "1.5.5" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "sphinx.ext.coverage", + "sphinx.ext.doctest", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "recommonmark", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_options = {"members": True} +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = "google-apps-card" +copyright = "2019, Google" +author = "Google APIs" + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = __version__ +# The short X.Y version. +version = ".".join(release.split(".")[0:2]) + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [ + "_build", + "**/.nox/**/*", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/snippets/README.rst", +] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + "description": "Google Cloud Client Libraries for google-apps-card", + "github_user": "googleapis", + "github_repo": "google-cloud-python", + "github_banner": True, + "font_family": "'Roboto', Georgia, sans", + "head_font_family": "'Roboto', Georgia, serif", + "code_font_family": "'Roboto Mono', 'Consolas', monospace", +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = "google-apps-card-doc" + +# -- Options for warnings ------------------------------------------------------ + + +suppress_warnings = [ + # Temporarily suppress this to avoid "more than one target found for + # cross-reference" warning, which are intractable for us to avoid while in + # a mono-repo. + # See https://github.com/sphinx-doc/sphinx/blob + # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 + "ref.python" +] + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Latex figure (float) alignment + #'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + root_doc, + "google-apps-card.tex", + "google-apps-card Documentation", + author, + "manual", + ) +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + root_doc, + "google-apps-card", + "google-apps-card Documentation", + [author], + 1, + ) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + root_doc, + "google-apps-card", + "google-apps-card Documentation", + author, + "google-apps-card", + "google-apps-card Library", + "APIs", + ) +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("https://python.readthedocs.org/en/latest/", None), + "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), + "google.api_core": ( + "https://googleapis.dev/python/google-api-core/latest/", + None, + ), + "grpc": ("https://grpc.github.io/grpc/python/", None), + "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# Napoleon settings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True diff --git a/packages/google-apps-card/docs/index.rst b/packages/google-apps-card/docs/index.rst new file mode 100644 index 000000000000..0eccdef92528 --- /dev/null +++ b/packages/google-apps-card/docs/index.rst @@ -0,0 +1,23 @@ +.. include:: README.rst + +.. include:: multiprocessing.rst + + +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + card_v1/services_ + card_v1/types_ + + +Changelog +--------- + +For a list of all ``google-apps-card`` releases: + +.. toctree:: + :maxdepth: 2 + + CHANGELOG diff --git a/packages/google-apps-card/docs/multiprocessing.rst b/packages/google-apps-card/docs/multiprocessing.rst new file mode 100644 index 000000000000..536d17b2ea65 --- /dev/null +++ b/packages/google-apps-card/docs/multiprocessing.rst @@ -0,0 +1,7 @@ +.. note:: + + Because this client uses :mod:`grpc` library, it is safe to + share instances across threads. In multiprocessing scenarios, the best + practice is to create client instances *after* the invocation of + :func:`os.fork` by :class:`multiprocessing.pool.Pool` or + :class:`multiprocessing.Process`. diff --git a/packages/google-apps-card/google/apps/card/__init__.py b/packages/google-apps-card/google/apps/card/__init__.py new file mode 100644 index 000000000000..5e3135c90efe --- /dev/null +++ b/packages/google-apps-card/google/apps/card/__init__.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from google.apps.card import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.apps.card_v1.types.card import ( + Action, + BorderStyle, + Button, + ButtonList, + Card, + Columns, + DateTimePicker, + DecoratedText, + Divider, + Grid, + Icon, + Image, + ImageComponent, + ImageCropStyle, + OnClick, + OpenLink, + SelectionInput, + Suggestions, + TextInput, + TextParagraph, + Widget, +) + +__all__ = ( + "Action", + "BorderStyle", + "Button", + "ButtonList", + "Card", + "Columns", + "DateTimePicker", + "DecoratedText", + "Divider", + "Grid", + "Icon", + "Image", + "ImageComponent", + "ImageCropStyle", + "OnClick", + "OpenLink", + "SelectionInput", + "Suggestions", + "TextInput", + "TextParagraph", + "Widget", +) diff --git a/packages/google-apps-card/google/apps/card/gapic_version.py b/packages/google-apps-card/google/apps/card/gapic_version.py new file mode 100644 index 000000000000..360a0d13ebdd --- /dev/null +++ b/packages/google-apps-card/google/apps/card/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-apps-card/google/apps/card/py.typed b/packages/google-apps-card/google/apps/card/py.typed new file mode 100644 index 000000000000..99846f9bd47e --- /dev/null +++ b/packages/google-apps-card/google/apps/card/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-apps-card package uses inline types. diff --git a/packages/google-apps-card/google/apps/card_v1/__init__.py b/packages/google-apps-card/google/apps/card_v1/__init__.py new file mode 100644 index 000000000000..e395fccb48b3 --- /dev/null +++ b/packages/google-apps-card/google/apps/card_v1/__init__.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from google.apps.card_v1 import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .types.card import ( + Action, + BorderStyle, + Button, + ButtonList, + Card, + Columns, + DateTimePicker, + DecoratedText, + Divider, + Grid, + Icon, + Image, + ImageComponent, + ImageCropStyle, + OnClick, + OpenLink, + SelectionInput, + Suggestions, + TextInput, + TextParagraph, + Widget, +) + +__all__ = ( + "Action", + "BorderStyle", + "Button", + "ButtonList", + "Card", + "Columns", + "DateTimePicker", + "DecoratedText", + "Divider", + "Grid", + "Icon", + "Image", + "ImageComponent", + "ImageCropStyle", + "OnClick", + "OpenLink", + "SelectionInput", + "Suggestions", + "TextInput", + "TextParagraph", + "Widget", +) diff --git a/packages/google-apps-card/google/apps/card_v1/gapic_metadata.json b/packages/google-apps-card/google/apps/card_v1/gapic_metadata.json new file mode 100644 index 000000000000..37ad6c64f8e7 --- /dev/null +++ b/packages/google-apps-card/google/apps/card_v1/gapic_metadata.json @@ -0,0 +1,7 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.apps.card_v1", + "protoPackage": "google.apps.card.v1", + "schema": "1.0" +} diff --git a/packages/google-apps-card/google/apps/card_v1/gapic_version.py b/packages/google-apps-card/google/apps/card_v1/gapic_version.py new file mode 100644 index 000000000000..360a0d13ebdd --- /dev/null +++ b/packages/google-apps-card/google/apps/card_v1/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-apps-card/google/apps/card_v1/py.typed b/packages/google-apps-card/google/apps/card_v1/py.typed new file mode 100644 index 000000000000..99846f9bd47e --- /dev/null +++ b/packages/google-apps-card/google/apps/card_v1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-apps-card package uses inline types. diff --git a/packages/google-apps-card/google/apps/card_v1/services/__init__.py b/packages/google-apps-card/google/apps/card_v1/services/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-apps-card/google/apps/card_v1/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-apps-card/google/apps/card_v1/types/__init__.py b/packages/google-apps-card/google/apps/card_v1/types/__init__.py new file mode 100644 index 000000000000..6a3c85e0d18a --- /dev/null +++ b/packages/google-apps-card/google/apps/card_v1/types/__init__.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from .card import ( + Action, + BorderStyle, + Button, + ButtonList, + Card, + Columns, + DateTimePicker, + DecoratedText, + Divider, + Grid, + Icon, + Image, + ImageComponent, + ImageCropStyle, + OnClick, + OpenLink, + SelectionInput, + Suggestions, + TextInput, + TextParagraph, + Widget, +) + +__all__ = ( + "Action", + "BorderStyle", + "Button", + "ButtonList", + "Card", + "Columns", + "DateTimePicker", + "DecoratedText", + "Divider", + "Grid", + "Icon", + "Image", + "ImageComponent", + "ImageCropStyle", + "OnClick", + "OpenLink", + "SelectionInput", + "Suggestions", + "TextInput", + "TextParagraph", + "Widget", +) diff --git a/packages/google-apps-card/google/apps/card_v1/types/card.py b/packages/google-apps-card/google/apps/card_v1/types/card.py new file mode 100644 index 000000000000..03de003dabe0 --- /dev/null +++ b/packages/google-apps-card/google/apps/card_v1/types/card.py @@ -0,0 +1,2886 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.type import color_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.apps.card.v1", + manifest={ + "Card", + "Widget", + "TextParagraph", + "Image", + "Divider", + "DecoratedText", + "TextInput", + "Suggestions", + "ButtonList", + "SelectionInput", + "DateTimePicker", + "Button", + "Icon", + "ImageCropStyle", + "BorderStyle", + "ImageComponent", + "Grid", + "Columns", + "OnClick", + "OpenLink", + "Action", + }, +) + + +class Card(proto.Message): + r"""A card interface displayed in a Google Chat message or Google + Workspace Add-on. + + Cards support a defined layout, interactive UI elements like + buttons, and rich media like images. Use cards to present detailed + information, gather information from users, and guide users to take + a next step. + + `Card builder `__ + + To learn how to build cards, see the following documentation: + + - For Google Chat apps, see `Design dynamic, interactive, and + consistent UIs with + cards `__. + - For Google Workspace Add-ons, see `Card-based + interfaces `__. + + **Example: Card message for a Google Chat app** + + |Example contact card| + + To create the sample card message in Google Chat, use the following + JSON: + + :: + + { + "cardsV2": [ + { + "cardId": "unique-card-id", + "card": { + "header": { + "title": "Sasha", + "subtitle": "Software Engineer", + "imageUrl": + "https://developers.google.com/chat/images/quickstart-app-avatar.png", + "imageType": "CIRCLE", + "imageAltText": "Avatar for Sasha", + }, + "sections": [ + { + "header": "Contact Info", + "collapsible": true, + "uncollapsibleWidgetsCount": 1, + "widgets": [ + { + "decoratedText": { + "startIcon": { + "knownIcon": "EMAIL", + }, + "text": "sasha@example.com", + } + }, + { + "decoratedText": { + "startIcon": { + "knownIcon": "PERSON", + }, + "text": "Online", + }, + }, + { + "decoratedText": { + "startIcon": { + "knownIcon": "PHONE", + }, + "text": "+1 (555) 555-1234", + } + }, + { + "buttonList": { + "buttons": [ + { + "text": "Share", + "onClick": { + "openLink": { + "url": "https://example.com/share", + } + } + }, + { + "text": "Edit", + "onClick": { + "action": { + "function": "goToView", + "parameters": [ + { + "key": "viewType", + "value": "EDIT", + } + ], + } + } + }, + ], + } + }, + ], + }, + ], + }, + } + ], + } + + .. |Example contact card| image:: https://developers.google.com/chat/images/card_api_reference.png + + Attributes: + header (google.apps.card_v1.types.Card.CardHeader): + The header of the card. A header usually + contains a leading image and a title. Headers + always appear at the top of a card. + sections (MutableSequence[google.apps.card_v1.types.Card.Section]): + Contains a collection of widgets. Each section has its own, + optional header. Sections are visually separated by a line + divider. For an example in Google Chat apps, see `Card + section `__. + section_divider_style (google.apps.card_v1.types.Card.DividerStyle): + The divider style between sections. + card_actions (MutableSequence[google.apps.card_v1.types.Card.CardAction]): + The card's actions. Actions are added to the card's toolbar + menu. + + `Google Workspace + Add-ons `__: + + For example, the following JSON constructs a card action + menu with ``Settings`` and ``Send Feedback`` options: + + :: + + "card_actions": [ + { + "actionLabel": "Settings", + "onClick": { + "action": { + "functionName": "goToView", + "parameters": [ + { + "key": "viewType", + "value": "SETTING" + } + ], + "loadIndicator": "LoadIndicator.SPINNER" + } + } + }, + { + "actionLabel": "Send Feedback", + "onClick": { + "openLink": { + "url": "https://example.com/feedback" + } + } + } + ] + name (str): + Name of the card. Used as a card identifier in card + navigation. + + `Google Workspace + Add-ons `__: + fixed_footer (google.apps.card_v1.types.Card.CardFixedFooter): + The fixed footer shown at the bottom of this card. + + Setting ``fixedFooter`` without specifying a + ``primaryButton`` or a ``secondaryButton`` causes an error. + For Chat apps, you can use fixed footers in + `dialogs `__, + but not `card + messages `__. + + `Google Workspace Add-ons and Chat + apps `__: + display_style (google.apps.card_v1.types.Card.DisplayStyle): + In Google Workspace Add-ons, sets the display properties of + the ``peekCardHeader``. + + `Google Workspace + Add-ons `__: + peek_card_header (google.apps.card_v1.types.Card.CardHeader): + When displaying contextual content, the peek card header + acts as a placeholder so that the user can navigate forward + between the homepage cards and the contextual cards. + + `Google Workspace + Add-ons `__: + """ + + class DividerStyle(proto.Enum): + r"""The divider style of a card. Currently only used for dividers + betweens card sections. + + `Google Workspace Add-ons and Chat + apps `__: + + Values: + DIVIDER_STYLE_UNSPECIFIED (0): + Don't use. Unspecified. + SOLID_DIVIDER (1): + Default option. Render a solid divider + between sections. + NO_DIVIDER (2): + If set, no divider is rendered between + sections. + """ + DIVIDER_STYLE_UNSPECIFIED = 0 + SOLID_DIVIDER = 1 + NO_DIVIDER = 2 + + class DisplayStyle(proto.Enum): + r"""In Google Workspace Add-ons, determines how a card is displayed. + + `Google Workspace + Add-ons `__: + + Values: + DISPLAY_STYLE_UNSPECIFIED (0): + Don't use. Unspecified. + PEEK (1): + The header of the card appears at the bottom + of the sidebar, partially covering the current + top card of the stack. Clicking the header pops + the card into the card stack. If the card has no + header, a generated header is used instead. + REPLACE (2): + Default value. The card is shown by replacing + the view of the top card in the card stack. + """ + DISPLAY_STYLE_UNSPECIFIED = 0 + PEEK = 1 + REPLACE = 2 + + class CardHeader(proto.Message): + r"""Represents a card header. For an example in Google Chat apps, see + `Card + header `__. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + title (str): + Required. The title of the card header. + The header has a fixed height: if both a + title and subtitle are specified, each takes up + one line. If only the title is specified, it + takes up both lines. + subtitle (str): + The subtitle of the card header. If specified, appears on + its own line below the ``title``. + image_type (google.apps.card_v1.types.Widget.ImageType): + The shape used to crop the image. + + `Google Workspace Add-ons and Chat + apps `__: + image_url (str): + The HTTPS URL of the image in the card + header. + image_alt_text (str): + The alternative text of this image that's + used for accessibility. + """ + + title: str = proto.Field( + proto.STRING, + number=1, + ) + subtitle: str = proto.Field( + proto.STRING, + number=2, + ) + image_type: "Widget.ImageType" = proto.Field( + proto.ENUM, + number=3, + enum="Widget.ImageType", + ) + image_url: str = proto.Field( + proto.STRING, + number=4, + ) + image_alt_text: str = proto.Field( + proto.STRING, + number=5, + ) + + class Section(proto.Message): + r"""A section contains a collection of widgets that are rendered + vertically in the order that they're specified. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + header (str): + Text that appears at the top of a section. Supports simple + HTML formatted text. For more information about formatting + text, see `Formatting text in Google Chat + apps `__ + and `Formatting text in Google Workspace + Add-ons `__. + widgets (MutableSequence[google.apps.card_v1.types.Widget]): + All the widgets in the section. + Must contain at least one widget. + collapsible (bool): + Indicates whether this section is collapsible. + + Collapsible sections hide some or all widgets, but users can + expand the section to reveal the hidden widgets by clicking + **Show more**. Users can hide the widgets again by clicking + **Show less**. + + To determine which widgets are hidden, specify + ``uncollapsibleWidgetsCount``. + uncollapsible_widgets_count (int): + The number of uncollapsible widgets which remain visible + even when a section is collapsed. + + For example, when a section contains five widgets and the + ``uncollapsibleWidgetsCount`` is set to ``2``, the first two + widgets are always shown and the last three are collapsed by + default. The ``uncollapsibleWidgetsCount`` is taken into + account only when ``collapsible`` is ``true``. + """ + + header: str = proto.Field( + proto.STRING, + number=1, + ) + widgets: MutableSequence["Widget"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="Widget", + ) + collapsible: bool = proto.Field( + proto.BOOL, + number=5, + ) + uncollapsible_widgets_count: int = proto.Field( + proto.INT32, + number=6, + ) + + class CardAction(proto.Message): + r"""A card action is the action associated with the card. For example, + an invoice card might include actions such as delete invoice, email + invoice, or open the invoice in a browser. + + `Google Workspace + Add-ons `__: + + Attributes: + action_label (str): + The label that displays as the action menu + item. + on_click (google.apps.card_v1.types.OnClick): + The ``onClick`` action for this action item. + """ + + action_label: str = proto.Field( + proto.STRING, + number=1, + ) + on_click: "OnClick" = proto.Field( + proto.MESSAGE, + number=2, + message="OnClick", + ) + + class CardFixedFooter(proto.Message): + r"""A persistent (sticky) footer that that appears at the bottom of the + card. + + Setting ``fixedFooter`` without specifying a ``primaryButton`` or a + ``secondaryButton`` causes an error. + + For Chat apps, you can use fixed footers in + `dialogs `__, + but not `card + messages `__. + For an example in Google Chat apps, see `Card + footer `__. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + primary_button (google.apps.card_v1.types.Button): + The primary button of the fixed footer. The + button must be a text button with text and color + set. + secondary_button (google.apps.card_v1.types.Button): + The secondary button of the fixed footer. The button must be + a text button with text and color set. If + ``secondaryButton`` is set, you must also set + ``primaryButton``. + """ + + primary_button: "Button" = proto.Field( + proto.MESSAGE, + number=1, + message="Button", + ) + secondary_button: "Button" = proto.Field( + proto.MESSAGE, + number=2, + message="Button", + ) + + header: CardHeader = proto.Field( + proto.MESSAGE, + number=1, + message=CardHeader, + ) + sections: MutableSequence[Section] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=Section, + ) + section_divider_style: DividerStyle = proto.Field( + proto.ENUM, + number=9, + enum=DividerStyle, + ) + card_actions: MutableSequence[CardAction] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=CardAction, + ) + name: str = proto.Field( + proto.STRING, + number=4, + ) + fixed_footer: CardFixedFooter = proto.Field( + proto.MESSAGE, + number=5, + message=CardFixedFooter, + ) + display_style: DisplayStyle = proto.Field( + proto.ENUM, + number=6, + enum=DisplayStyle, + ) + peek_card_header: CardHeader = proto.Field( + proto.MESSAGE, + number=7, + message=CardHeader, + ) + + +class Widget(proto.Message): + r"""Each card is made up of widgets. + + A widget is a composite object that can represent one of text, + images, buttons, and other object types. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + text_paragraph (google.apps.card_v1.types.TextParagraph): + Displays a text paragraph. Supports simple HTML formatted + text. For more information about formatting text, see + `Formatting text in Google Chat + apps `__ + and `Formatting text in Google Workspace + Add-ons `__. + + For example, the following JSON creates a bolded text: + + :: + + "textParagraph": { + "text": " bold text" + } + + This field is a member of `oneof`_ ``data``. + image (google.apps.card_v1.types.Image): + Displays an image. + + For example, the following JSON creates an image with + alternative text: + + :: + + "image": { + "imageUrl": + "https://developers.google.com/chat/images/quickstart-app-avatar.png", + "altText": "Chat app avatar" + } + + This field is a member of `oneof`_ ``data``. + decorated_text (google.apps.card_v1.types.DecoratedText): + Displays a decorated text item. + + For example, the following JSON creates a decorated text + widget showing email address: + + :: + + "decoratedText": { + "icon": { + "knownIcon": "EMAIL" + }, + "topLabel": "Email Address", + "text": "sasha@example.com", + "bottomLabel": "This is a new Email address!", + "switchControl": { + "name": "has_send_welcome_email_to_sasha", + "selected": false, + "controlType": "CHECKBOX" + } + } + + This field is a member of `oneof`_ ``data``. + button_list (google.apps.card_v1.types.ButtonList): + A list of buttons. + + For example, the following JSON creates two buttons. The + first is a blue text button and the second is an image + button that opens a link: + + :: + + "buttonList": { + "buttons": [ + { + "text": "Edit", + "color": { + "red": 0, + "green": 0, + "blue": 1, + "alpha": 1 + }, + "disabled": true, + }, + { + "icon": { + "knownIcon": "INVITE", + "altText": "check calendar" + }, + "onClick": { + "openLink": { + "url": "https://example.com/calendar" + } + } + } + ] + } + + This field is a member of `oneof`_ ``data``. + text_input (google.apps.card_v1.types.TextInput): + Displays a text box that users can type into. + + For example, the following JSON creates a text input for an + email address: + + :: + + "textInput": { + "name": "mailing_address", + "label": "Mailing Address" + } + + As another example, the following JSON creates a text input + for a programming language with static suggestions: + + :: + + "textInput": { + "name": "preferred_programing_language", + "label": "Preferred Language", + "initialSuggestions": { + "items": [ + { + "text": "C++" + }, + { + "text": "Java" + }, + { + "text": "JavaScript" + }, + { + "text": "Python" + } + ] + } + } + + This field is a member of `oneof`_ ``data``. + selection_input (google.apps.card_v1.types.SelectionInput): + Displays a selection control that lets users select items. + Selection controls can be checkboxes, radio buttons, + switches, or dropdown menus. + + For example, the following JSON creates a dropdown menu that + lets users choose a size: + + :: + + "selectionInput": { + "name": "size", + "label": "Size" + "type": "DROPDOWN", + "items": [ + { + "text": "S", + "value": "small", + "selected": false + }, + { + "text": "M", + "value": "medium", + "selected": true + }, + { + "text": "L", + "value": "large", + "selected": false + }, + { + "text": "XL", + "value": "extra_large", + "selected": false + } + ] + } + + This field is a member of `oneof`_ ``data``. + date_time_picker (google.apps.card_v1.types.DateTimePicker): + Displays a widget that lets users input a date, time, or + date and time. + + For example, the following JSON creates a date time picker + to schedule an appointment: + + :: + + "dateTimePicker": { + "name": "appointment_time", + "label": "Book your appointment at:", + "type": "DATE_AND_TIME", + "valueMsEpoch": "796435200000" + } + + This field is a member of `oneof`_ ``data``. + divider (google.apps.card_v1.types.Divider): + Displays a horizontal line divider between widgets. + + For example, the following JSON creates a divider: + + :: + + "divider": { + } + + This field is a member of `oneof`_ ``data``. + grid (google.apps.card_v1.types.Grid): + Displays a grid with a collection of items. + + A grid supports any number of columns and items. The number + of rows is determined by the upper bounds of the number + items divided by the number of columns. A grid with 10 items + and 2 columns has 5 rows. A grid with 11 items and 2 columns + has 6 rows. + + `Google Workspace Add-ons and Chat + apps `__: + + For example, the following JSON creates a 2 column grid with + a single item: + + :: + + "grid": { + "title": "A fine collection of items", + "columnCount": 2, + "borderStyle": { + "type": "STROKE", + "cornerRadius": 4 + }, + "items": [ + { + "image": { + "imageUri": "https://www.example.com/image.png", + "cropStyle": { + "type": "SQUARE" + }, + "borderStyle": { + "type": "STROKE" + } + }, + "title": "An item", + "textAlignment": "CENTER" + } + ], + "onClick": { + "openLink": { + "url": "https://www.example.com" + } + } + } + + This field is a member of `oneof`_ ``data``. + columns (google.apps.card_v1.types.Columns): + Displays up to 2 columns. + + To include more than 2 columns, or to use rows, use the + ``Grid`` widget. + + For example, the following JSON creates 2 columns that each + contain text paragraphs: + + :: + + "columns": { + "columnItems": [ + { + "horizontalSizeStyle": "FILL_AVAILABLE_SPACE", + "horizontalAlignment": "CENTER", + "verticalAlignment": "CENTER", + "widgets": [ + { + "textParagraph": { + "text": "First column text paragraph" + } + } + ] + }, + { + "horizontalSizeStyle": "FILL_AVAILABLE_SPACE", + "horizontalAlignment": "CENTER", + "verticalAlignment": "CENTER", + "widgets": [ + { + "textParagraph": { + "text": "Second column text paragraph" + } + } + ] + } + ] + } + + This field is a member of `oneof`_ ``data``. + horizontal_alignment (google.apps.card_v1.types.Widget.HorizontalAlignment): + Specifies whether widgets align to the left, + right, or center of a column. + """ + + class ImageType(proto.Enum): + r"""The shape used to crop the image. + + `Google Workspace Add-ons and Chat + apps `__: + + Values: + SQUARE (0): + Default value. Applies a square mask to the + image. For example, a 4x3 image becomes 3x3. + CIRCLE (1): + Applies a circular mask to the image. For + example, a 4x3 image becomes a circle with a + diameter of 3. + """ + SQUARE = 0 + CIRCLE = 1 + + class HorizontalAlignment(proto.Enum): + r"""Specifies whether widgets align to the left, right, or center of a + column. + + `Google Chat apps `__: + + Values: + HORIZONTAL_ALIGNMENT_UNSPECIFIED (0): + Don't use. Unspecified. + START (1): + Default value. Aligns widgets to the start + position of the column. For left-to-right + layouts, aligns to the left. For right-to-left + layouts, aligns to the right. + CENTER (2): + Aligns widgets to the center of the column. + END (3): + Aligns widgets to the end position of the + column. For left-to-right layouts, aligns + widgets to the right. For right-to-left layouts, + aligns widgets to the left. + """ + HORIZONTAL_ALIGNMENT_UNSPECIFIED = 0 + START = 1 + CENTER = 2 + END = 3 + + text_paragraph: "TextParagraph" = proto.Field( + proto.MESSAGE, + number=1, + oneof="data", + message="TextParagraph", + ) + image: "Image" = proto.Field( + proto.MESSAGE, + number=2, + oneof="data", + message="Image", + ) + decorated_text: "DecoratedText" = proto.Field( + proto.MESSAGE, + number=3, + oneof="data", + message="DecoratedText", + ) + button_list: "ButtonList" = proto.Field( + proto.MESSAGE, + number=4, + oneof="data", + message="ButtonList", + ) + text_input: "TextInput" = proto.Field( + proto.MESSAGE, + number=5, + oneof="data", + message="TextInput", + ) + selection_input: "SelectionInput" = proto.Field( + proto.MESSAGE, + number=6, + oneof="data", + message="SelectionInput", + ) + date_time_picker: "DateTimePicker" = proto.Field( + proto.MESSAGE, + number=7, + oneof="data", + message="DateTimePicker", + ) + divider: "Divider" = proto.Field( + proto.MESSAGE, + number=9, + oneof="data", + message="Divider", + ) + grid: "Grid" = proto.Field( + proto.MESSAGE, + number=10, + oneof="data", + message="Grid", + ) + columns: "Columns" = proto.Field( + proto.MESSAGE, + number=11, + oneof="data", + message="Columns", + ) + horizontal_alignment: HorizontalAlignment = proto.Field( + proto.ENUM, + number=8, + enum=HorizontalAlignment, + ) + + +class TextParagraph(proto.Message): + r"""A paragraph of text that supports formatting. For an example in + Google Chat apps, see `Text + paragraph `__. + For more information about formatting text, see `Formatting text in + Google Chat + apps `__ + and `Formatting text in Google Workspace + Add-ons `__. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + text (str): + The text that's shown in the widget. + """ + + text: str = proto.Field( + proto.STRING, + number=1, + ) + + +class Image(proto.Message): + r"""An image that is specified by a URL and can have an ``onClick`` + action. For an example, see + `Image `__. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + image_url (str): + The HTTPS URL that hosts the image. + + For example: + + :: + + https://developers.google.com/chat/images/quickstart-app-avatar.png + on_click (google.apps.card_v1.types.OnClick): + When a user clicks the image, the click + triggers this action. + alt_text (str): + The alternative text of this image that's + used for accessibility. + """ + + image_url: str = proto.Field( + proto.STRING, + number=1, + ) + on_click: "OnClick" = proto.Field( + proto.MESSAGE, + number=2, + message="OnClick", + ) + alt_text: str = proto.Field( + proto.STRING, + number=3, + ) + + +class Divider(proto.Message): + r"""Displays a divider between widgets as a horizontal line. For an + example in Google Chat apps, see + `Divider `__. + + `Google Workspace Add-ons and Chat + apps `__: + + For example, the following JSON creates a divider: + + :: + + "divider": {} + + """ + + +class DecoratedText(proto.Message): + r"""A widget that displays text with optional decorations such as a + label above or below the text, an icon in front of the text, a + selection widget, or a button after the text. For an example in + Google Chat apps, see `Decorated + text `__. + + `Google Workspace Add-ons and Chat + apps `__: + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + icon (google.apps.card_v1.types.Icon): + Deprecated in favor of ``startIcon``. + start_icon (google.apps.card_v1.types.Icon): + The icon displayed in front of the text. + top_label (str): + The text that appears above ``text``. Always truncates. + text (str): + Required. The primary text. + + Supports simple formatting. For more information about + formatting text, see `Formatting text in Google Chat + apps `__ + and `Formatting text in Google Workspace + Add-ons `__. + wrap_text (bool): + The wrap text setting. If ``true``, the text wraps and + displays on multiple lines. Otherwise, the text is + truncated. + + Only applies to ``text``, not ``topLabel`` and + ``bottomLabel``. + bottom_label (str): + The text that appears below ``text``. Always wraps. + on_click (google.apps.card_v1.types.OnClick): + This action is triggered when users click ``topLabel`` or + ``bottomLabel``. + button (google.apps.card_v1.types.Button): + A button that a user can click to trigger an + action. + + This field is a member of `oneof`_ ``control``. + switch_control (google.apps.card_v1.types.DecoratedText.SwitchControl): + A switch widget that a user can click to + change its state and trigger an action. + + This field is a member of `oneof`_ ``control``. + end_icon (google.apps.card_v1.types.Icon): + An icon displayed after the text. + + Supports + `built-in `__ + and + `custom `__ + icons. + + This field is a member of `oneof`_ ``control``. + """ + + class SwitchControl(proto.Message): + r"""Either a toggle-style switch or a checkbox inside a + ``decoratedText`` widget. + + `Google Workspace Add-ons and Chat + apps `__: + + Only supported in the ``decoratedText`` widget. + + Attributes: + name (str): + The name by which the switch widget is identified in a form + input event. + + For details about working with form inputs, see `Receive + form + data `__. + value (str): + The value entered by a user, returned as part of a form + input event. + + For details about working with form inputs, see `Receive + form + data `__. + selected (bool): + When ``true``, the switch is selected. + on_change_action (google.apps.card_v1.types.Action): + The action to perform when the switch state + is changed, such as what function to run. + control_type (google.apps.card_v1.types.DecoratedText.SwitchControl.ControlType): + How the switch appears in the user interface. + + `Google Workspace Add-ons and Chat + apps `__: + """ + + class ControlType(proto.Enum): + r"""How the switch appears in the user interface. + + `Google Workspace Add-ons and Chat + apps `__: + + Values: + SWITCH (0): + A toggle-style switch. + CHECKBOX (1): + Deprecated in favor of ``CHECK_BOX``. + CHECK_BOX (2): + A checkbox. + """ + SWITCH = 0 + CHECKBOX = 1 + CHECK_BOX = 2 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + selected: bool = proto.Field( + proto.BOOL, + number=3, + ) + on_change_action: "Action" = proto.Field( + proto.MESSAGE, + number=4, + message="Action", + ) + control_type: "DecoratedText.SwitchControl.ControlType" = proto.Field( + proto.ENUM, + number=5, + enum="DecoratedText.SwitchControl.ControlType", + ) + + icon: "Icon" = proto.Field( + proto.MESSAGE, + number=1, + message="Icon", + ) + start_icon: "Icon" = proto.Field( + proto.MESSAGE, + number=12, + message="Icon", + ) + top_label: str = proto.Field( + proto.STRING, + number=3, + ) + text: str = proto.Field( + proto.STRING, + number=4, + ) + wrap_text: bool = proto.Field( + proto.BOOL, + number=5, + ) + bottom_label: str = proto.Field( + proto.STRING, + number=6, + ) + on_click: "OnClick" = proto.Field( + proto.MESSAGE, + number=7, + message="OnClick", + ) + button: "Button" = proto.Field( + proto.MESSAGE, + number=8, + oneof="control", + message="Button", + ) + switch_control: SwitchControl = proto.Field( + proto.MESSAGE, + number=9, + oneof="control", + message=SwitchControl, + ) + end_icon: "Icon" = proto.Field( + proto.MESSAGE, + number=11, + oneof="control", + message="Icon", + ) + + +class TextInput(proto.Message): + r"""A field in which users can enter text. Supports suggestions and + on-change actions. For an example in Google Chat apps, see `Text + input `__. + + Chat apps receive and can process the value of entered text during + form input events. For details about working with form inputs, see + `Receive form + data `__. + + When you need to collect undefined or abstract data from users, use + a text input. To collect defined or enumerated data from users, use + the [SelectionInput][google.apps.card.v1.SelectionInput] widget. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + name (str): + The name by which the text input is identified in a form + input event. + + For details about working with form inputs, see `Receive + form + data `__. + label (str): + The text that appears above the text input field in the user + interface. + + Specify text that helps the user enter the information your + app needs. For example, if you are asking someone's name, + but specifically need their surname, write ``surname`` + instead of ``name``. + + Required if ``hintText`` is unspecified. Otherwise, + optional. + hint_text (str): + Text that appears below the text input field meant to assist + users by prompting them to enter a certain value. This text + is always visible. + + Required if ``label`` is unspecified. Otherwise, optional. + value (str): + The value entered by a user, returned as part of a form + input event. + + For details about working with form inputs, see `Receive + form + data `__. + type_ (google.apps.card_v1.types.TextInput.Type): + How a text input field appears in the user + interface. For example, whether the field is + single or multi-line. + on_change_action (google.apps.card_v1.types.Action): + What to do when a change occurs in the text input field. For + example, a user adding to the field or deleting text. + + Examples of actions to take include running a custom + function or opening a + `dialog `__ + in Google Chat. + initial_suggestions (google.apps.card_v1.types.Suggestions): + Suggested values that users can enter. These values appear + when users click inside the text input field. As users type, + the suggested values dynamically filter to match what the + users have typed. + + For example, a text input field for programming language + might suggest Java, JavaScript, Python, and C++. When users + start typing ``Jav``, the list of suggestions filters to + show just ``Java`` and ``JavaScript``. + + Suggested values help guide users to enter values that your + app can make sense of. When referring to JavaScript, some + users might enter ``javascript`` and others ``java script``. + Suggesting ``JavaScript`` can standardize how users interact + with your app. + + When specified, ``TextInput.type`` is always + ``SINGLE_LINE``, even if it's set to ``MULTIPLE_LINE``. + + `Google Workspace Add-ons and Chat + apps `__: + auto_complete_action (google.apps.card_v1.types.Action): + Optional. Specify what action to take when the text input + field provides suggestions to users who interact with it. + + If unspecified, the suggestions are set by + ``initialSuggestions`` and are processed by the client. + + If specified, the app takes the action specified here, such + as running a custom function. + + `Google Workspace + Add-ons `__: + placeholder_text (str): + Text that appears in the text input field when the field is + empty. Use this text to prompt users to enter a value. For + example, ``Enter a number from 0 to 100``. + + `Google Chat apps `__: + """ + + class Type(proto.Enum): + r"""How a text input field appears in the user interface. For example, + whether it's a single line input field, or a multi-line input. If + ``initialSuggestions`` is specified, ``type`` is always + ``SINGLE_LINE``, even if it's set to ``MULTIPLE_LINE``. + + `Google Workspace Add-ons and Chat + apps `__: + + Values: + SINGLE_LINE (0): + The text input field has a fixed height of + one line. + MULTIPLE_LINE (1): + The text input field has a fixed height of + multiple lines. + """ + SINGLE_LINE = 0 + MULTIPLE_LINE = 1 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + label: str = proto.Field( + proto.STRING, + number=2, + ) + hint_text: str = proto.Field( + proto.STRING, + number=3, + ) + value: str = proto.Field( + proto.STRING, + number=4, + ) + type_: Type = proto.Field( + proto.ENUM, + number=5, + enum=Type, + ) + on_change_action: "Action" = proto.Field( + proto.MESSAGE, + number=6, + message="Action", + ) + initial_suggestions: "Suggestions" = proto.Field( + proto.MESSAGE, + number=7, + message="Suggestions", + ) + auto_complete_action: "Action" = proto.Field( + proto.MESSAGE, + number=8, + message="Action", + ) + placeholder_text: str = proto.Field( + proto.STRING, + number=12, + ) + + +class Suggestions(proto.Message): + r"""Suggested values that users can enter. These values appear when + users click inside the text input field. As users type, the + suggested values dynamically filter to match what the users have + typed. + + For example, a text input field for programming language might + suggest Java, JavaScript, Python, and C++. When users start typing + ``Jav``, the list of suggestions filters to show ``Java`` and + ``JavaScript``. + + Suggested values help guide users to enter values that your app can + make sense of. When referring to JavaScript, some users might enter + ``javascript`` and others ``java script``. Suggesting ``JavaScript`` + can standardize how users interact with your app. + + When specified, ``TextInput.type`` is always ``SINGLE_LINE``, even + if it's set to ``MULTIPLE_LINE``. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + items (MutableSequence[google.apps.card_v1.types.Suggestions.SuggestionItem]): + A list of suggestions used for autocomplete + recommendations in text input fields. + """ + + class SuggestionItem(proto.Message): + r"""One suggested value that users can enter in a text input field. + + `Google Workspace Add-ons and Chat + apps `__: + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + text (str): + The value of a suggested input to a text + input field. This is equivalent to what users + enter themselves. + + This field is a member of `oneof`_ ``content``. + """ + + text: str = proto.Field( + proto.STRING, + number=1, + oneof="content", + ) + + items: MutableSequence[SuggestionItem] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=SuggestionItem, + ) + + +class ButtonList(proto.Message): + r"""A list of buttons layed out horizontally. For an example in Google + Chat apps, see `Button + list `__. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + buttons (MutableSequence[google.apps.card_v1.types.Button]): + An array of buttons. + """ + + buttons: MutableSequence["Button"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Button", + ) + + +class SelectionInput(proto.Message): + r"""A widget that creates one or more UI items that users can select. + For example, a dropdown menu or checkboxes. You can use this widget + to collect data that can be predicted or enumerated. For an example + in Google Chat apps, see `Selection + input `__. + + Chat apps can process the value of items that users select or input. + For details about working with form inputs, see `Receive form + data `__. + + To collect undefined or abstract data from users, use the + [TextInput][google.apps.card.v1.TextInput] widget. + + `Google Workspace Add-ons and Chat + apps `__: + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + The name that identifies the selection input in a form input + event. + + For details about working with form inputs, see `Receive + form + data `__. + label (str): + The text that appears above the selection + input field in the user interface. + + Specify text that helps the user enter the + information your app needs. For example, if + users are selecting the urgency of a work ticket + from a drop-down menu, the label might be + "Urgency" or "Select urgency". + type_ (google.apps.card_v1.types.SelectionInput.SelectionType): + The type of items that are displayed to users in a + ``SelectionInput`` widget. Selection types support different + types of interactions. For example, users can select one or + more checkboxes, but they can only select one value from a + dropdown menu. + items (MutableSequence[google.apps.card_v1.types.SelectionInput.SelectionItem]): + An array of selectable items. For example, an + array of radio buttons or checkboxes. Supports + up to 100 items. + on_change_action (google.apps.card_v1.types.Action): + If specified, the form is submitted when the selection + changes. If not specified, you must specify a separate + button that submits the form. + + For details about working with form inputs, see `Receive + form + data `__. + multi_select_max_selected_items (int): + For multiselect menus, the maximum number of + items that a user can select. Minimum value is 1 + item. If unspecified, defaults to 3 items. + multi_select_min_query_length (int): + For multiselect menus, the number of text + characters that a user inputs before the Chat + app queries autocomplete and displays suggested + items in the menu. + + If unspecified, defaults to 0 characters for + static data sources and 3 characters for + external data sources. + external_data_source (google.apps.card_v1.types.Action): + An external data source, such as a relational + data base. + + This field is a member of `oneof`_ ``multi_select_data_source``. + platform_data_source (google.apps.card_v1.types.SelectionInput.PlatformDataSource): + A data source from Google Workspace. + + This field is a member of `oneof`_ ``multi_select_data_source``. + """ + + class SelectionType(proto.Enum): + r"""The format for the items that users can select. Different options + support different types of interactions. For example, users can + select multiple checkboxes, but can only select one item from a + dropdown menu. + + Each selection input supports one type of selection. Mixing + checkboxes and switches, for example, isn't supported. + + `Google Workspace Add-ons and Chat + apps `__: + + Values: + CHECK_BOX (0): + A set of checkboxes. Users can select one or + more checkboxes. + RADIO_BUTTON (1): + A set of radio buttons. Users can select one + radio button. + SWITCH (2): + A set of switches. Users can turn on one or + more switches. + DROPDOWN (3): + A dropdown menu. Users can select one item + from the menu. + MULTI_SELECT (4): + A multiselect menu for static or dynamic data. From the menu + bar, users select one or more items. Users can also input + values to populate dynamic data. For example, users can + start typing the name of a Google Chat space and the widget + autosuggests the space. + + To populate items for a multiselect menu, you can use one of + the following types of data sources: + + - Static data: Items are specified as ``SelectionItem`` + objects in the widget. Up to 100 items. + - Google Workspace data: Items are populated using data + from Google Workspace, such as Google Workspace users or + Google Chat spaces. + - External data: Items are populated from an external data + source outside of Google Workspace. + + For examples of how to implement multiselect menus, see the + ```SelectionInput`` widget + page `__. + + `Google Workspace Add-ons and Chat + apps `__: + multiselect for Google Workspace Add-ons are in `Developer + Preview `__. + """ + CHECK_BOX = 0 + RADIO_BUTTON = 1 + SWITCH = 2 + DROPDOWN = 3 + MULTI_SELECT = 4 + + class SelectionItem(proto.Message): + r"""An item that users can select in a selection input, such as a + checkbox or switch. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + text (str): + The text that identifies or describes the + item to users. + value (str): + The value associated with this item. The client should use + this as a form input value. + + For details about working with form inputs, see `Receive + form + data `__. + selected (bool): + Whether the item is selected by default. If + the selection input only accepts one value (such + as for radio buttons or a dropdown menu), only + set this field for one item. + start_icon_uri (str): + For multiselect menus, the URL for the icon displayed next + to the item's ``text`` field. Supports PNG and JPEG files. + Must be an ``HTTPS`` URL. For example, + ``https://developers.google.com/chat/images/quickstart-app-avatar.png``. + bottom_text (str): + For multiselect menus, a text description or label that's + displayed below the item's ``text`` field. + """ + + text: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + selected: bool = proto.Field( + proto.BOOL, + number=3, + ) + start_icon_uri: str = proto.Field( + proto.STRING, + number=4, + ) + bottom_text: str = proto.Field( + proto.STRING, + number=5, + ) + + class PlatformDataSource(proto.Message): + r"""For a [``SelectionInput``][google.apps.card.v1.SelectionInput] + widget that uses a multiselect menu, a data source from Google + Workspace. Used to populate items in a multiselect menu. + + `Google Chat apps `__: + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + common_data_source (google.apps.card_v1.types.SelectionInput.PlatformDataSource.CommonDataSource): + A data source shared by all Google Workspace + applications, such as users in a Google + Workspace organization. + + This field is a member of `oneof`_ ``data_source``. + """ + + class CommonDataSource(proto.Enum): + r"""A data source shared by all [Google Workspace applications] + (https://developers.google.com/chat/api/reference/rest/v1/HostApp). + + `Google Chat apps `__: + + Values: + UNKNOWN (0): + Default value. Don't use. + USER (1): + Google Workspace users. The user can only + view and select users from their Google + Workspace organization. + """ + UNKNOWN = 0 + USER = 1 + + common_data_source: "SelectionInput.PlatformDataSource.CommonDataSource" = ( + proto.Field( + proto.ENUM, + number=1, + oneof="data_source", + enum="SelectionInput.PlatformDataSource.CommonDataSource", + ) + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + label: str = proto.Field( + proto.STRING, + number=2, + ) + type_: SelectionType = proto.Field( + proto.ENUM, + number=3, + enum=SelectionType, + ) + items: MutableSequence[SelectionItem] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=SelectionItem, + ) + on_change_action: "Action" = proto.Field( + proto.MESSAGE, + number=5, + message="Action", + ) + multi_select_max_selected_items: int = proto.Field( + proto.INT32, + number=6, + ) + multi_select_min_query_length: int = proto.Field( + proto.INT32, + number=7, + ) + external_data_source: "Action" = proto.Field( + proto.MESSAGE, + number=8, + oneof="multi_select_data_source", + message="Action", + ) + platform_data_source: PlatformDataSource = proto.Field( + proto.MESSAGE, + number=9, + oneof="multi_select_data_source", + message=PlatformDataSource, + ) + + +class DateTimePicker(proto.Message): + r"""Lets users input a date, a time, or both a date and a time. For an + example in Google Chat apps, see `Date time + picker `__. + + Users can input text or use the picker to select dates and times. If + users input an invalid date or time, the picker shows an error that + prompts users to input the information correctly. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + name (str): + The name by which the ``DateTimePicker`` is identified in a + form input event. + + For details about working with form inputs, see `Receive + form + data `__. + label (str): + The text that prompts users to input a date, a time, or a + date and time. For example, if users are scheduling an + appointment, use a label such as ``Appointment date`` or + ``Appointment date and time``. + type_ (google.apps.card_v1.types.DateTimePicker.DateTimePickerType): + Whether the widget supports inputting a date, + a time, or the date and time. + value_ms_epoch (int): + The default value displayed in the widget, in milliseconds + since `Unix epoch + time `__. + + Specify the value based on the type of picker + (``DateTimePickerType``): + + - ``DATE_AND_TIME``: a calendar date and time in UTC. For + example, to represent January 1, 2023 at 12:00 PM UTC, + use ``1672574400000``. + - ``DATE_ONLY``: a calendar date at 00:00:00 UTC. For + example, to represent January 1, 2023, use + ``1672531200000``. + - ``TIME_ONLY``: a time in UTC. For example, to represent + 12:00 PM, use ``43200000`` (or ``12 * 60 * 60 * 1000``). + timezone_offset_date (int): + The number representing the time zone offset from UTC, in + minutes. If set, the ``value_ms_epoch`` is displayed in the + specified time zone. If unset, the value defaults to the + user's time zone setting. + on_change_action (google.apps.card_v1.types.Action): + Triggered when the user clicks **Save** or **Clear** from + the ``DateTimePicker`` interface. + """ + + class DateTimePickerType(proto.Enum): + r"""The format for the date and time in the ``DateTimePicker`` widget. + Determines whether users can input a date, a time, or both a date + and time. + + `Google Workspace Add-ons and Chat + apps `__: + + Values: + DATE_AND_TIME (0): + Users input a date and time. + DATE_ONLY (1): + Users input a date. + TIME_ONLY (2): + Users input a time. + """ + DATE_AND_TIME = 0 + DATE_ONLY = 1 + TIME_ONLY = 2 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + label: str = proto.Field( + proto.STRING, + number=2, + ) + type_: DateTimePickerType = proto.Field( + proto.ENUM, + number=3, + enum=DateTimePickerType, + ) + value_ms_epoch: int = proto.Field( + proto.INT64, + number=4, + ) + timezone_offset_date: int = proto.Field( + proto.INT32, + number=5, + ) + on_change_action: "Action" = proto.Field( + proto.MESSAGE, + number=6, + message="Action", + ) + + +class Button(proto.Message): + r"""A text, icon, or text and icon button that users can click. For an + example in Google Chat apps, see `Button + list `__. + + To make an image a clickable button, specify an + [``Image``][google.apps.card.v1.Image] (not an + [``ImageComponent``][google.apps.card.v1.ImageComponent]) and set an + ``onClick`` action. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + text (str): + The text displayed inside the button. + icon (google.apps.card_v1.types.Icon): + The icon image. If both ``icon`` and ``text`` are set, then + the icon appears before the text. + color (google.type.color_pb2.Color): + If set, the button is filled with a solid background color + and the font color changes to maintain contrast with the + background color. For example, setting a blue background + likely results in white text. + + If unset, the image background is white and the font color + is blue. + + For red, green, and blue, the value of each field is a + ``float`` number that you can express in either of two ways: + as a number between 0 and 255 divided by 255 (153/255), or + as a value between 0 and 1 (0.6). 0 represents the absence + of a color and 1 or 255/255 represent the full presence of + that color on the RGB scale. + + Optionally set ``alpha``, which sets a level of transparency + using this equation: + + :: + + pixel color = alpha * (this color) + (1.0 - alpha) * (background color) + + For ``alpha``, a value of ``1`` corresponds with a solid + color, and a value of ``0`` corresponds with a completely + transparent color. + + For example, the following color represents a half + transparent red: + + :: + + "color": { + "red": 1, + "green": 0, + "blue": 0, + "alpha": 0.5 + } + on_click (google.apps.card_v1.types.OnClick): + Required. The action to perform when a user + clicks the button, such as opening a hyperlink + or running a custom function. + disabled (bool): + If ``true``, the button is displayed in an inactive state + and doesn't respond to user actions. + alt_text (str): + The alternative text that's used for + accessibility. + Set descriptive text that lets users know what + the button does. For example, if a button opens + a hyperlink, you might write: "Opens a new + browser tab and navigates to the Google Chat + developer documentation at + https://developers.google.com/chat". + """ + + text: str = proto.Field( + proto.STRING, + number=1, + ) + icon: "Icon" = proto.Field( + proto.MESSAGE, + number=2, + message="Icon", + ) + color: color_pb2.Color = proto.Field( + proto.MESSAGE, + number=3, + message=color_pb2.Color, + ) + on_click: "OnClick" = proto.Field( + proto.MESSAGE, + number=4, + message="OnClick", + ) + disabled: bool = proto.Field( + proto.BOOL, + number=5, + ) + alt_text: str = proto.Field( + proto.STRING, + number=6, + ) + + +class Icon(proto.Message): + r"""An icon displayed in a widget on a card. For an example in Google + Chat apps, see + `Icon `__. + + Supports + `built-in `__ + and + `custom `__ + icons. + + `Google Workspace Add-ons and Chat + apps `__: + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + known_icon (str): + Display one of the built-in icons provided by Google + Workspace. + + For example, to display an airplane icon, specify + ``AIRPLANE``. For a bus, specify ``BUS``. + + For a full list of supported icons, see `built-in + icons `__. + + This field is a member of `oneof`_ ``icons``. + icon_url (str): + Display a custom icon hosted at an HTTPS URL. + + For example: + + :: + + "iconUrl": + "https://developers.google.com/chat/images/quickstart-app-avatar.png" + + Supported file types include ``.png`` and ``.jpg``. + + This field is a member of `oneof`_ ``icons``. + alt_text (str): + Optional. A description of the icon used for accessibility. + If unspecified, the default value ``Button`` is provided. As + a best practice, you should set a helpful description for + what the icon displays, and if applicable, what it does. For + example, ``A user's account portrait``, or + ``Opens a new browser tab and navigates to the Google Chat developer documentation at https://developers.google.com/chat``. + + If the icon is set in a + [``Button``][google.apps.card.v1.Button], the ``altText`` + appears as helper text when the user hovers over the button. + However, if the button also sets ``text``, the icon's + ``altText`` is ignored. + image_type (google.apps.card_v1.types.Widget.ImageType): + The crop style applied to the image. In some cases, applying + a ``CIRCLE`` crop causes the image to be drawn larger than a + built-in icon. + """ + + known_icon: str = proto.Field( + proto.STRING, + number=1, + oneof="icons", + ) + icon_url: str = proto.Field( + proto.STRING, + number=2, + oneof="icons", + ) + alt_text: str = proto.Field( + proto.STRING, + number=3, + ) + image_type: "Widget.ImageType" = proto.Field( + proto.ENUM, + number=4, + enum="Widget.ImageType", + ) + + +class ImageCropStyle(proto.Message): + r"""Represents the crop style applied to an image. + + `Google Workspace Add-ons and Chat + apps `__: + + For example, here's how to apply a 16:9 aspect ratio: + + :: + + cropStyle { + "type": "RECTANGLE_CUSTOM", + "aspectRatio": 16/9 + } + + Attributes: + type_ (google.apps.card_v1.types.ImageCropStyle.ImageCropType): + The crop type. + aspect_ratio (float): + The aspect ratio to use if the crop type is + ``RECTANGLE_CUSTOM``. + + For example, here's how to apply a 16:9 aspect ratio: + + :: + + cropStyle { + "type": "RECTANGLE_CUSTOM", + "aspectRatio": 16/9 + } + """ + + class ImageCropType(proto.Enum): + r"""Represents the crop style applied to an image. + + `Google Workspace Add-ons and Chat + apps `__: + + Values: + IMAGE_CROP_TYPE_UNSPECIFIED (0): + Don't use. Unspecified. + SQUARE (1): + Default value. Applies a square crop. + CIRCLE (2): + Applies a circular crop. + RECTANGLE_CUSTOM (3): + Applies a rectangular crop with a custom aspect ratio. Set + the custom aspect ratio with ``aspectRatio``. + RECTANGLE_4_3 (4): + Applies a rectangular crop with a 4:3 aspect + ratio. + """ + IMAGE_CROP_TYPE_UNSPECIFIED = 0 + SQUARE = 1 + CIRCLE = 2 + RECTANGLE_CUSTOM = 3 + RECTANGLE_4_3 = 4 + + type_: ImageCropType = proto.Field( + proto.ENUM, + number=1, + enum=ImageCropType, + ) + aspect_ratio: float = proto.Field( + proto.DOUBLE, + number=2, + ) + + +class BorderStyle(proto.Message): + r"""The style options for the border of a card or widget, including the + border type and color. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + type_ (google.apps.card_v1.types.BorderStyle.BorderType): + The border type. + stroke_color (google.type.color_pb2.Color): + The colors to use when the type is ``BORDER_TYPE_STROKE``. + corner_radius (int): + The corner radius for the border. + """ + + class BorderType(proto.Enum): + r"""Represents the border types applied to widgets. + + `Google Workspace Add-ons and Chat + apps `__: + + Values: + BORDER_TYPE_UNSPECIFIED (0): + Don't use. Unspecified. + NO_BORDER (1): + Default value. No border. + STROKE (2): + Outline. + """ + BORDER_TYPE_UNSPECIFIED = 0 + NO_BORDER = 1 + STROKE = 2 + + type_: BorderType = proto.Field( + proto.ENUM, + number=1, + enum=BorderType, + ) + stroke_color: color_pb2.Color = proto.Field( + proto.MESSAGE, + number=2, + message=color_pb2.Color, + ) + corner_radius: int = proto.Field( + proto.INT32, + number=3, + ) + + +class ImageComponent(proto.Message): + r"""Represents an image. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + image_uri (str): + The image URL. + alt_text (str): + The accessibility label for the image. + crop_style (google.apps.card_v1.types.ImageCropStyle): + The crop style to apply to the image. + border_style (google.apps.card_v1.types.BorderStyle): + The border style to apply to the image. + """ + + image_uri: str = proto.Field( + proto.STRING, + number=1, + ) + alt_text: str = proto.Field( + proto.STRING, + number=2, + ) + crop_style: "ImageCropStyle" = proto.Field( + proto.MESSAGE, + number=3, + message="ImageCropStyle", + ) + border_style: "BorderStyle" = proto.Field( + proto.MESSAGE, + number=4, + message="BorderStyle", + ) + + +class Grid(proto.Message): + r"""Displays a grid with a collection of items. Items can only include + text or images. For responsive columns, or to include more than text + or images, use [``Columns``][google.apps.card.v1.Columns]. For an + example in Google Chat apps, see + `Grid `__. + + A grid supports any number of columns and items. The number of rows + is determined by items divided by columns. A grid with 10 items and + 2 columns has 5 rows. A grid with 11 items and 2 columns has 6 rows. + + `Google Workspace Add-ons and Chat + apps `__: + + For example, the following JSON creates a 2 column grid with a + single item: + + :: + + "grid": { + "title": "A fine collection of items", + "columnCount": 2, + "borderStyle": { + "type": "STROKE", + "cornerRadius": 4 + }, + "items": [ + { + "image": { + "imageUri": "https://www.example.com/image.png", + "cropStyle": { + "type": "SQUARE" + }, + "borderStyle": { + "type": "STROKE" + } + }, + "title": "An item", + "textAlignment": "CENTER" + } + ], + "onClick": { + "openLink": { + "url": "https://www.example.com" + } + } + } + + Attributes: + title (str): + The text that displays in the grid header. + items (MutableSequence[google.apps.card_v1.types.Grid.GridItem]): + The items to display in the grid. + border_style (google.apps.card_v1.types.BorderStyle): + The border style to apply to each grid item. + column_count (int): + The number of columns to display in the grid. + A default value is used if this field isn't + specified, and that default value is different + depending on where the grid is shown (dialog + versus companion). + on_click (google.apps.card_v1.types.OnClick): + This callback is reused by each individual + grid item, but with the item's identifier and + index in the items list added to the callback's + parameters. + """ + + class GridItem(proto.Message): + r"""Represents an item in a grid layout. Items can contain text, an + image, or both text and an image. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + id (str): + A user-specified identifier for this grid item. This + identifier is returned in the parent grid's ``onClick`` + callback parameters. + image (google.apps.card_v1.types.ImageComponent): + The image that displays in the grid item. + title (str): + The grid item's title. + subtitle (str): + The grid item's subtitle. + layout (google.apps.card_v1.types.Grid.GridItem.GridItemLayout): + The layout to use for the grid item. + """ + + class GridItemLayout(proto.Enum): + r"""Represents the various layout options available for a grid item. + + `Google Workspace Add-ons and Chat + apps `__: + + Values: + GRID_ITEM_LAYOUT_UNSPECIFIED (0): + Don't use. Unspecified. + TEXT_BELOW (1): + The title and subtitle are shown below the + grid item's image. + TEXT_ABOVE (2): + The title and subtitle are shown above the + grid item's image. + """ + GRID_ITEM_LAYOUT_UNSPECIFIED = 0 + TEXT_BELOW = 1 + TEXT_ABOVE = 2 + + id: str = proto.Field( + proto.STRING, + number=1, + ) + image: "ImageComponent" = proto.Field( + proto.MESSAGE, + number=2, + message="ImageComponent", + ) + title: str = proto.Field( + proto.STRING, + number=3, + ) + subtitle: str = proto.Field( + proto.STRING, + number=4, + ) + layout: "Grid.GridItem.GridItemLayout" = proto.Field( + proto.ENUM, + number=9, + enum="Grid.GridItem.GridItemLayout", + ) + + title: str = proto.Field( + proto.STRING, + number=1, + ) + items: MutableSequence[GridItem] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=GridItem, + ) + border_style: "BorderStyle" = proto.Field( + proto.MESSAGE, + number=3, + message="BorderStyle", + ) + column_count: int = proto.Field( + proto.INT32, + number=4, + ) + on_click: "OnClick" = proto.Field( + proto.MESSAGE, + number=5, + message="OnClick", + ) + + +class Columns(proto.Message): + r"""The ``Columns`` widget displays up to 2 columns in a card or dialog. + You can add widgets to each column; the widgets appear in the order + that they are specified. For an example in Google Chat apps, see + `Columns `__. + + The height of each column is determined by the taller column. For + example, if the first column is taller than the second column, both + columns have the height of the first column. Because each column can + contain a different number of widgets, you can't define rows or + align widgets between the columns. + + Columns are displayed side-by-side. You can customize the width of + each column using the ``HorizontalSizeStyle`` field. If the user's + screen width is too narrow, the second column wraps below the first: + + - On web, the second column wraps if the screen width is less than + or equal to 480 pixels. + - On iOS devices, the second column wraps if the screen width is + less than or equal to 300 pt. + - On Android devices, the second column wraps if the screen width + is less than or equal to 320 dp. + + To include more than 2 columns, or to use rows, use the + [``Grid``][google.apps.card.v1.Grid] widget. + + `Google Workspace Add-ons and Chat + apps `__: Columns + for Google Workspace Add-ons are in `Developer + Preview `__. + + Attributes: + column_items (MutableSequence[google.apps.card_v1.types.Columns.Column]): + An array of columns. You can include up to 2 + columns in a card or dialog. + """ + + class Column(proto.Message): + r"""A column. + + `Google Chat apps `__: + + Attributes: + horizontal_size_style (google.apps.card_v1.types.Columns.Column.HorizontalSizeStyle): + Specifies how a column fills the width of the card. + + `Google Chat apps `__: + horizontal_alignment (google.apps.card_v1.types.Widget.HorizontalAlignment): + Specifies whether widgets align to the left, + right, or center of a column. + vertical_alignment (google.apps.card_v1.types.Columns.Column.VerticalAlignment): + Specifies whether widgets align to the top, bottom, or + center of a column. + + `Google Chat apps `__: + widgets (MutableSequence[google.apps.card_v1.types.Columns.Column.Widgets]): + An array of widgets included in a column. + Widgets appear in the order that they are + specified. + """ + + class HorizontalSizeStyle(proto.Enum): + r"""Specifies how a column fills the width of the card. The width of + each column depends on both the ``HorizontalSizeStyle`` and the + width of the widgets within the column. + + `Google Chat apps `__: + + Values: + HORIZONTAL_SIZE_STYLE_UNSPECIFIED (0): + Don't use. Unspecified. + FILL_AVAILABLE_SPACE (1): + Default value. Column fills the available space, up to 70% + of the card's width. If both columns are set to + ``FILL_AVAILABLE_SPACE``, each column fills 50% of the + space. + FILL_MINIMUM_SPACE (2): + Column fills the least amount of space + possible and no more than 30% of the card's + width. + """ + HORIZONTAL_SIZE_STYLE_UNSPECIFIED = 0 + FILL_AVAILABLE_SPACE = 1 + FILL_MINIMUM_SPACE = 2 + + class VerticalAlignment(proto.Enum): + r"""Specifies whether widgets align to the top, bottom, or center of a + column. + + `Google Chat apps `__: + + Values: + VERTICAL_ALIGNMENT_UNSPECIFIED (0): + Don't use. Unspecified. + CENTER (1): + Default value. Aligns widgets to the center + of a column. + TOP (2): + Aligns widgets to the top of a column. + BOTTOM (3): + Aligns widgets to the bottom of a column. + """ + VERTICAL_ALIGNMENT_UNSPECIFIED = 0 + CENTER = 1 + TOP = 2 + BOTTOM = 3 + + class Widgets(proto.Message): + r"""The supported widgets that you can include in a column. + + `Google Chat apps `__: + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + text_paragraph (google.apps.card_v1.types.TextParagraph): + [TextParagraph][google.apps.card.v1.TextParagraph] widget. + + This field is a member of `oneof`_ ``data``. + image (google.apps.card_v1.types.Image): + [Image][google.apps.card.v1.Image] widget. + + This field is a member of `oneof`_ ``data``. + decorated_text (google.apps.card_v1.types.DecoratedText): + [DecoratedText][google.apps.card.v1.DecoratedText] widget. + + This field is a member of `oneof`_ ``data``. + button_list (google.apps.card_v1.types.ButtonList): + [ButtonList][google.apps.card.v1.ButtonList] widget. + + This field is a member of `oneof`_ ``data``. + text_input (google.apps.card_v1.types.TextInput): + [TextInput][google.apps.card.v1.TextInput] widget. + + This field is a member of `oneof`_ ``data``. + selection_input (google.apps.card_v1.types.SelectionInput): + [SelectionInput][google.apps.card.v1.SelectionInput] widget. + + This field is a member of `oneof`_ ``data``. + date_time_picker (google.apps.card_v1.types.DateTimePicker): + [DateTimePicker][google.apps.card.v1.DateTimePicker] widget. + + This field is a member of `oneof`_ ``data``. + """ + + text_paragraph: "TextParagraph" = proto.Field( + proto.MESSAGE, + number=1, + oneof="data", + message="TextParagraph", + ) + image: "Image" = proto.Field( + proto.MESSAGE, + number=2, + oneof="data", + message="Image", + ) + decorated_text: "DecoratedText" = proto.Field( + proto.MESSAGE, + number=3, + oneof="data", + message="DecoratedText", + ) + button_list: "ButtonList" = proto.Field( + proto.MESSAGE, + number=4, + oneof="data", + message="ButtonList", + ) + text_input: "TextInput" = proto.Field( + proto.MESSAGE, + number=5, + oneof="data", + message="TextInput", + ) + selection_input: "SelectionInput" = proto.Field( + proto.MESSAGE, + number=6, + oneof="data", + message="SelectionInput", + ) + date_time_picker: "DateTimePicker" = proto.Field( + proto.MESSAGE, + number=7, + oneof="data", + message="DateTimePicker", + ) + + horizontal_size_style: "Columns.Column.HorizontalSizeStyle" = proto.Field( + proto.ENUM, + number=1, + enum="Columns.Column.HorizontalSizeStyle", + ) + horizontal_alignment: "Widget.HorizontalAlignment" = proto.Field( + proto.ENUM, + number=2, + enum="Widget.HorizontalAlignment", + ) + vertical_alignment: "Columns.Column.VerticalAlignment" = proto.Field( + proto.ENUM, + number=3, + enum="Columns.Column.VerticalAlignment", + ) + widgets: MutableSequence["Columns.Column.Widgets"] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="Columns.Column.Widgets", + ) + + column_items: MutableSequence[Column] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=Column, + ) + + +class OnClick(proto.Message): + r"""Represents how to respond when users click an interactive element on + a card, such as a button. + + `Google Workspace Add-ons and Chat + apps `__: + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + action (google.apps.card_v1.types.Action): + If specified, an action is triggered by this ``onClick``. + + This field is a member of `oneof`_ ``data``. + open_link (google.apps.card_v1.types.OpenLink): + If specified, this ``onClick`` triggers an open link action. + + This field is a member of `oneof`_ ``data``. + open_dynamic_link_action (google.apps.card_v1.types.Action): + An add-on triggers this action when the action needs to open + a link. This differs from the ``open_link`` above in that + this needs to talk to server to get the link. Thus some + preparation work is required for web client to do before the + open link action response comes back. + + `Google Workspace + Add-ons `__: + + This field is a member of `oneof`_ ``data``. + card (google.apps.card_v1.types.Card): + A new card is pushed to the card stack after clicking if + specified. + + `Google Workspace + Add-ons `__: + + This field is a member of `oneof`_ ``data``. + """ + + action: "Action" = proto.Field( + proto.MESSAGE, + number=1, + oneof="data", + message="Action", + ) + open_link: "OpenLink" = proto.Field( + proto.MESSAGE, + number=2, + oneof="data", + message="OpenLink", + ) + open_dynamic_link_action: "Action" = proto.Field( + proto.MESSAGE, + number=3, + oneof="data", + message="Action", + ) + card: "Card" = proto.Field( + proto.MESSAGE, + number=4, + oneof="data", + message="Card", + ) + + +class OpenLink(proto.Message): + r"""Represents an ``onClick`` event that opens a hyperlink. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + url (str): + The URL to open. + open_as (google.apps.card_v1.types.OpenLink.OpenAs): + How to open a link. + + `Google Workspace + Add-ons `__: + on_close (google.apps.card_v1.types.OpenLink.OnClose): + Whether the client forgets about a link after opening it, or + observes it until the window closes. + + `Google Workspace + Add-ons `__: + """ + + class OpenAs(proto.Enum): + r"""When an ``OnClick`` action opens a link, then the client can either + open it as a full-size window (if that's the frame used by the + client), or an overlay (such as a pop-up). The implementation + depends on the client platform capabilities, and the value selected + might be ignored if the client doesn't support it. ``FULL_SIZE`` is + supported by all clients. + + `Google Workspace + Add-ons `__: + + Values: + FULL_SIZE (0): + The link opens as a full-size window (if + that's the frame used by the client). + OVERLAY (1): + The link opens as an overlay, such as a + pop-up. + """ + FULL_SIZE = 0 + OVERLAY = 1 + + class OnClose(proto.Enum): + r"""What the client does when a link opened by an ``OnClick`` action is + closed. + + Implementation depends on client platform capabilities. For example, + a web browser might open a link in a pop-up window with an + ``OnClose`` handler. + + If both ``OnOpen`` and ``OnClose`` handlers are set, and the client + platform can't support both values, ``OnClose`` takes precedence. + + `Google Workspace + Add-ons `__: + + Values: + NOTHING (0): + Default value. The card doesn't reload; + nothing happens. + RELOAD (1): + Reloads the card after the child window closes. + + If used in conjunction with + ```OpenAs.OVERLAY`` `__, + the child window acts as a modal dialog and the parent card + is blocked until the child window closes. + """ + NOTHING = 0 + RELOAD = 1 + + url: str = proto.Field( + proto.STRING, + number=1, + ) + open_as: OpenAs = proto.Field( + proto.ENUM, + number=2, + enum=OpenAs, + ) + on_close: OnClose = proto.Field( + proto.ENUM, + number=3, + enum=OnClose, + ) + + +class Action(proto.Message): + r"""An action that describes the behavior when the form is submitted. + For example, you can invoke an Apps Script script to handle the + form. If the action is triggered, the form values are sent to the + server. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + function (str): + A custom function to invoke when the containing element is + clicked or othrwise activated. + + For example usage, see `Create interactive + cards `__. + parameters (MutableSequence[google.apps.card_v1.types.Action.ActionParameter]): + List of action parameters. + load_indicator (google.apps.card_v1.types.Action.LoadIndicator): + Specifies the loading indicator that the + action displays while making the call to the + action. + persist_values (bool): + Indicates whether form values persist after the action. The + default value is ``false``. + + If ``true``, form values remain after the action is + triggered. To let the user make changes while the action is + being processed, set + ```LoadIndicator`` `__ + to ``NONE``. For `card + messages `__ + in Chat apps, you must also set the action's + ```ResponseType`` `__ + to ``UPDATE_MESSAGE`` and use the same + ```card_id`` `__ + from the card that contained the action. + + If ``false``, the form values are cleared when the action is + triggered. To prevent the user from making changes while the + action is being processed, set + ```LoadIndicator`` `__ + to ``SPINNER``. + interaction (google.apps.card_v1.types.Action.Interaction): + Optional. Required when opening a + `dialog `__. + + What to do in response to an interaction with a user, such + as a user clicking a button in a card message. + + If unspecified, the app responds by executing an + ``action``—like opening a link or running a function—as + normal. + + By specifying an ``interaction``, the app can respond in + special interactive ways. For example, by setting + ``interaction`` to ``OPEN_DIALOG``, the app can open a + `dialog `__. + When specified, a loading indicator isn't shown. If + specified for an add-on, the entire card is stripped and + nothing is shown in the client. + + `Google Chat apps `__: + """ + + class LoadIndicator(proto.Enum): + r"""Specifies the loading indicator that the action displays while + making the call to the action. + + `Google Workspace Add-ons and Chat + apps `__: + + Values: + SPINNER (0): + Displays a spinner to indicate that content + is loading. + NONE (1): + Nothing is displayed. + """ + SPINNER = 0 + NONE = 1 + + class Interaction(proto.Enum): + r"""Optional. Required when opening a + `dialog `__. + + What to do in response to an interaction with a user, such as a user + clicking a button in a card message. + + If unspecified, the app responds by executing an ``action``—like + opening a link or running a function—as normal. + + By specifying an ``interaction``, the app can respond in special + interactive ways. For example, by setting ``interaction`` to + ``OPEN_DIALOG``, the app can open a + `dialog `__. + + When specified, a loading indicator isn't shown. If specified for an + add-on, the entire card is stripped and nothing is shown in the + client. + + `Google Chat apps `__: + + Values: + INTERACTION_UNSPECIFIED (0): + Default value. The ``action`` executes as normal. + OPEN_DIALOG (1): + Opens a + `dialog `__, + a windowed, card-based interface that Chat apps use to + interact with users. + + Only supported by Chat apps in response to button-clicks on + card messages. If specified for an add-on, the entire card + is stripped and nothing is shown in the client. + + `Google Chat apps `__: + """ + INTERACTION_UNSPECIFIED = 0 + OPEN_DIALOG = 1 + + class ActionParameter(proto.Message): + r"""List of string parameters to supply when the action method is + invoked. For example, consider three snooze buttons: snooze now, + snooze one day, or snooze next week. You might use + ``action method = snooze()``, passing the snooze type and snooze + time in the list of string parameters. + + To learn more, see + ```CommonEventObject`` `__. + + `Google Workspace Add-ons and Chat + apps `__: + + Attributes: + key (str): + The name of the parameter for the action + script. + value (str): + The value of the parameter. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + function: str = proto.Field( + proto.STRING, + number=1, + ) + parameters: MutableSequence[ActionParameter] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=ActionParameter, + ) + load_indicator: LoadIndicator = proto.Field( + proto.ENUM, + number=3, + enum=LoadIndicator, + ) + persist_values: bool = proto.Field( + proto.BOOL, + number=4, + ) + interaction: Interaction = proto.Field( + proto.ENUM, + number=5, + enum=Interaction, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-apps-card/mypy.ini b/packages/google-apps-card/mypy.ini new file mode 100644 index 000000000000..574c5aed394b --- /dev/null +++ b/packages/google-apps-card/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/packages/google-apps-card/noxfile.py b/packages/google-apps-card/noxfile.py new file mode 100644 index 000000000000..1e6cd48d0529 --- /dev/null +++ b/packages/google-apps-card/noxfile.py @@ -0,0 +1,428 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2023 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. + +# Generated by synthtool. DO NOT EDIT! + +from __future__ import absolute_import + +import os +import pathlib +import re +import shutil +from typing import Dict, List +import warnings + +import nox + +BLACK_VERSION = "black[jupyter]==23.7.0" +ISORT_VERSION = "isort==5.11.0" + +LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] + + +DEFAULT_PYTHON_VERSION = "3.10" + +UNIT_TEST_PYTHON_VERSIONS: List[str] = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] +UNIT_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "asyncmock", + "pytest", + "pytest-cov", + "pytest-asyncio", +] +UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_DEPENDENCIES: List[str] = [] +UNIT_TEST_EXTRAS: List[str] = [] +UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12"] +SYSTEM_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "pytest", + "google-cloud-testutils", +] +SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_EXTRAS: List[str] = [] +SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +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): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", BLACK_VERSION) + session.run( + "black", + "--check", + *LINT_PATHS, + ) + + session.run("flake8", "google", "tests") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + session.run( + "black", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run( + "isort", + "--fss", + *LINT_PATHS, + ) + session.run( + "black", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") + + +def install_unittest_dependencies(session, *constraints): + standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES + session.install(*standard_deps, *constraints) + + if UNIT_TEST_EXTERNAL_DEPENDENCIES: + warnings.warn( + "'unit_test_external_dependencies' is deprecated. Instead, please " + "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", + DeprecationWarning, + ) + session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_LOCAL_DEPENDENCIES: + session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_EXTRAS_BY_PYTHON: + extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif UNIT_TEST_EXTRAS: + extras = UNIT_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +def default(session): + # Install all test dependencies, then install this package in-place. + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + install_unittest_dependencies(session, "-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", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + os.path.join("tests", "unit"), + *session.posargs, + ) + + +@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) +def unit(session): + """Run the unit test suite.""" + default(session) + + +def install_systemtest_dependencies(session, *constraints): + # Use pre-release gRPC for system tests. + # Exclude version 1.52.0rc1 which has a known issue. + # See https://github.com/grpc/grpc/issues/32163 + session.install("--pre", "grpcio!=1.52.0rc1") + + session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: + session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_LOCAL_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTRAS_BY_PYTHON: + extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif SYSTEM_TEST_EXTRAS: + extras = SYSTEM_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@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") + + # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. + if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": + session.skip("RUN_SYSTEM_TESTS is set to false, skipping") + # 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) + # Sanity check: only run tests if found. + if not system_test_exists and not system_test_folder_exists: + session.skip("System tests were not found") + + install_systemtest_dependencies(session, "-c", constraints_path) + + # Run py.test against the system tests. + if system_test_exists: + 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", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def cover(session): + """Run the final coverage report. + + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=100") + + session.run("coverage", "erase") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "sphinx==4.5.0", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "gcp-sphinx-docfx-yaml", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python="3.12") +def prerelease_deps(session): + """Run all tests with prerelease versions of dependencies installed.""" + + # Install all dependencies + session.install("-e", ".[all, tests, tracing]") + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + system_deps_all = ( + SYSTEM_TEST_STANDARD_DEPENDENCIES + + SYSTEM_TEST_EXTERNAL_DEPENDENCIES + + SYSTEM_TEST_EXTRAS + ) + session.install(*system_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY + / "testing" + / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + session.install(*constraints_deps) + + prerel_deps = [ + "protobuf", + # dependency of grpc + "six", + "googleapis-common-protos", + # Exclude version 1.52.0rc1 which has a known issue. See https://github.com/grpc/grpc/issues/32163 + "grpcio!=1.52.0rc1", + "grpcio-status", + "google-api-core", + "google-auth", + "proto-plus", + "google-cloud-testutils", + # dependencies of google-cloud-testutils" + "click", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--upgrade", dep) + + # Remaining dependencies + other_deps = [ + "requests", + ] + session.install(*other_deps) + + # Print out prerelease package versions + session.run( + "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" + ) + session.run("python", "-c", "import grpc; print(grpc.__version__)") + session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + + session.run("py.test", "tests/unit") diff --git a/packages/google-apps-card/scripts/decrypt-secrets.sh b/packages/google-apps-card/scripts/decrypt-secrets.sh new file mode 100755 index 000000000000..0018b421ddf8 --- /dev/null +++ b/packages/google-apps-card/scripts/decrypt-secrets.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright 2023 Google LLC All rights reserved. +# +# 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. + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ROOT=$( dirname "$DIR" ) + +# Work from the project root. +cd $ROOT + +# Prevent it from overriding files. +# We recommend that sample authors use their own service account files and cloud project. +# In that case, they are supposed to prepare these files by themselves. +if [[ -f "testing/test-env.sh" ]] || \ + [[ -f "testing/service-account.json" ]] || \ + [[ -f "testing/client-secrets.json" ]]; then + echo "One or more target files exist, aborting." + exit 1 +fi + +# Use SECRET_MANAGER_PROJECT if set, fallback to cloud-devrel-kokoro-resources. +PROJECT_ID="${SECRET_MANAGER_PROJECT:-cloud-devrel-kokoro-resources}" + +gcloud secrets versions access latest --secret="python-docs-samples-test-env" \ + --project="${PROJECT_ID}" \ + > testing/test-env.sh +gcloud secrets versions access latest \ + --secret="python-docs-samples-service-account" \ + --project="${PROJECT_ID}" \ + > testing/service-account.json +gcloud secrets versions access latest \ + --secret="python-docs-samples-client-secrets" \ + --project="${PROJECT_ID}" \ + > testing/client-secrets.json diff --git a/packages/google-apps-card/scripts/fixup_card_v1_keywords.py b/packages/google-apps-card/scripts/fixup_card_v1_keywords.py new file mode 100644 index 000000000000..c3a186eb181b --- /dev/null +++ b/packages/google-apps-card/scripts/fixup_card_v1_keywords.py @@ -0,0 +1,175 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +class cardCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=cardCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the card client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/packages/google-apps-card/setup.py b/packages/google-apps-card/setup.py new file mode 100644 index 000000000000..14f1a8c4aff9 --- /dev/null +++ b/packages/google-apps-card/setup.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import io +import os +import re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = "google-apps-card" + + +description = "Google Apps Card API client library" + +version = None + +with open(os.path.join(package_root, "google/apps/card/gapic_version.py")) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert len(version_candidates) == 1 + version = version_candidates[0] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 1.34.1, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "google-auth >= 2.14.1, <3.0.0dev", + "proto-plus >= 1.22.3, <2.0.0dev", + "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-card" + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package + for package in setuptools.find_namespace_packages() + if package.startswith("google") +] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache 2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + install_requires=dependencies, + include_package_data=True, + zip_safe=False, +) diff --git a/packages/google-apps-card/testing/.gitignore b/packages/google-apps-card/testing/.gitignore new file mode 100644 index 000000000000..b05fbd630881 --- /dev/null +++ b/packages/google-apps-card/testing/.gitignore @@ -0,0 +1,3 @@ +test-env.sh +service-account.json +client-secrets.json \ No newline at end of file diff --git a/packages/google-apps-card/testing/constraints-3.10.txt b/packages/google-apps-card/testing/constraints-3.10.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-apps-card/testing/constraints-3.10.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-apps-card/testing/constraints-3.11.txt b/packages/google-apps-card/testing/constraints-3.11.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-apps-card/testing/constraints-3.11.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-apps-card/testing/constraints-3.12.txt b/packages/google-apps-card/testing/constraints-3.12.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-apps-card/testing/constraints-3.12.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-apps-card/testing/constraints-3.7.txt b/packages/google-apps-card/testing/constraints-3.7.txt new file mode 100644 index 000000000000..b8a550c73855 --- /dev/null +++ b/packages/google-apps-card/testing/constraints-3.7.txt @@ -0,0 +1,10 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file. +# Pin the version to the lower bound. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", +# Then this file should have google-cloud-foo==1.14.0 +google-api-core==1.34.1 +google-auth==2.14.1 +proto-plus==1.22.3 +protobuf==3.19.5 diff --git a/packages/google-apps-card/testing/constraints-3.8.txt b/packages/google-apps-card/testing/constraints-3.8.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-apps-card/testing/constraints-3.8.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-apps-card/testing/constraints-3.9.txt b/packages/google-apps-card/testing/constraints-3.9.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-apps-card/testing/constraints-3.9.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-apps-card/tests/__init__.py b/packages/google-apps-card/tests/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-apps-card/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-apps-card/tests/unit/__init__.py b/packages/google-apps-card/tests/unit/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-apps-card/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-apps-card/tests/unit/gapic/__init__.py b/packages/google-apps-card/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-apps-card/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-apps-card/tests/unit/gapic/card_v1/__init__.py b/packages/google-apps-card/tests/unit/gapic/card_v1/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-apps-card/tests/unit/gapic/card_v1/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-apps-card/tests/unit/gapic/card_v1/test_card.py b/packages/google-apps-card/tests/unit/gapic/card_v1/test_card.py new file mode 100644 index 000000000000..f47dcfa976f4 --- /dev/null +++ b/packages/google-apps-card/tests/unit/gapic/card_v1/test_card.py @@ -0,0 +1,23 @@ +# Copyright 2024 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. +# + +from google.apps import card_v1 + +# NOTE: These are dummy tests to reach 100% coverage +# They simply check that the message can be created. + + +def test_card(): + card_v1.Card() From 9bd042d41f29c27131ae4710e5933dbbe4bf3a69 Mon Sep 17 00:00:00 2001 From: yoshi-code-bot <70984784+yoshi-code-bot@users.noreply.github.com> Date: Thu, 29 Feb 2024 10:15:48 -0800 Subject: [PATCH 03/13] chore: Update release-please config files (#12372) Update release-please config files --- .release-please-manifest.json | 1 + release-please-config.json | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 435ceac24c9b..5d7d68e6a24d 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -2,6 +2,7 @@ "packages/google-ai-generativelanguage": "0.5.3", "packages/google-analytics-admin": "0.22.6", "packages/google-analytics-data": "0.18.6", + "packages/google-apps-card": "0.0.0", "packages/google-apps-meet": "0.1.5", "packages/google-apps-script-type": "0.3.7", "packages/google-area120-tables": "0.11.8", diff --git a/release-please-config.json b/release-please-config.json index ed598febdf4b..b2337a569b93 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -70,6 +70,16 @@ ], "release-type": "python" }, + "packages/google-apps-card": { + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "component": "google-apps-card", + "extra-files": [ + "google/apps/card/gapic_version.py", + "google/apps/card_v1/gapic_version.py" + ], + "release-type": "python" + }, "packages/google-apps-meet": { "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, From db1411133fbdd2ee333aca125dd05996c7a95f59 Mon Sep 17 00:00:00 2001 From: "owlbot-bootstrapper[bot]" <104649659+owlbot-bootstrapper[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 13:40:32 -0500 Subject: [PATCH 04/13] feat: add initial files for google.cloud.parallelstore.v1beta (#12368) Source-Link: https://github.com/googleapis/googleapis-gen/commit/ac0d5d8cce099ed4c66e74309c44bac30afcf3a3 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLXBhcmFsbGVsc3RvcmUvLk93bEJvdC55YW1sIiwiaCI6ImFjMGQ1ZDhjY2UwOTllZDRjNjZlNzQzMDljNDRiYWMzMGFmY2YzYTMifQ== PiperOrigin-RevId: 0 --------- Co-authored-by: Owlbot Bootstrapper Co-authored-by: Owl Bot Co-authored-by: Anthonios Partheniou --- .../google-cloud-parallelstore/.OwlBot.yaml | 18 + .../google-cloud-parallelstore/.coveragerc | 13 + packages/google-cloud-parallelstore/.flake8 | 33 + .../google-cloud-parallelstore/.gitignore | 63 + .../.repo-metadata.json | 17 + .../google-cloud-parallelstore/CHANGELOG.md | 1 + .../CODE_OF_CONDUCT.md | 95 + .../CONTRIBUTING.rst | 271 + packages/google-cloud-parallelstore/LICENSE | 202 + .../google-cloud-parallelstore/MANIFEST.in | 25 + .../google-cloud-parallelstore/README.rst | 108 + .../docs/CHANGELOG.md | 1 + .../docs/README.rst | 1 + .../docs/_static/custom.css | 20 + .../docs/_templates/layout.html | 50 + .../google-cloud-parallelstore/docs/conf.py | 384 + .../google-cloud-parallelstore/docs/index.rst | 23 + .../docs/multiprocessing.rst | 7 + .../parallelstore_v1beta/parallelstore.rst | 10 + .../docs/parallelstore_v1beta/services_.rst | 6 + .../docs/parallelstore_v1beta/types_.rst | 6 + .../google/cloud/parallelstore/__init__.py | 49 + .../cloud/parallelstore/gapic_version.py | 16 + .../google/cloud/parallelstore/py.typed | 2 + .../cloud/parallelstore_v1beta/__init__.py | 44 + .../parallelstore_v1beta/gapic_metadata.json | 103 + .../parallelstore_v1beta/gapic_version.py | 16 + .../cloud/parallelstore_v1beta/py.typed | 2 + .../parallelstore_v1beta/services/__init__.py | 15 + .../services/parallelstore/__init__.py | 22 + .../services/parallelstore/async_client.py | 1281 ++++ .../services/parallelstore/client.py | 1736 +++++ .../services/parallelstore/pagers.py | 155 + .../parallelstore/transports/__init__.py | 36 + .../services/parallelstore/transports/base.py | 279 + .../services/parallelstore/transports/grpc.py | 515 ++ .../parallelstore/transports/grpc_asyncio.py | 525 ++ .../services/parallelstore/transports/rest.py | 1432 ++++ .../parallelstore_v1beta/types/__init__.py | 36 + .../types/parallelstore.py | 486 ++ packages/google-cloud-parallelstore/mypy.ini | 3 + .../google-cloud-parallelstore/noxfile.py | 428 ++ ...ted_parallelstore_create_instance_async.py | 61 + ...ated_parallelstore_create_instance_sync.py | 61 + ...ted_parallelstore_delete_instance_async.py | 56 + ...ated_parallelstore_delete_instance_sync.py | 56 + ...erated_parallelstore_get_instance_async.py | 52 + ...nerated_parallelstore_get_instance_sync.py | 52 + ...ated_parallelstore_list_instances_async.py | 53 + ...rated_parallelstore_list_instances_sync.py | 53 + ...ted_parallelstore_update_instance_async.py | 59 + ...ated_parallelstore_update_instance_sync.py | 59 + ...ata_google.cloud.parallelstore.v1beta.json | 844 +++ .../scripts/decrypt-secrets.sh | 46 + .../fixup_parallelstore_v1beta_keywords.py | 180 + packages/google-cloud-parallelstore/setup.py | 93 + .../testing/.gitignore | 3 + .../testing/constraints-3.10.txt | 6 + .../testing/constraints-3.11.txt | 6 + .../testing/constraints-3.12.txt | 6 + .../testing/constraints-3.7.txt | 10 + .../testing/constraints-3.8.txt | 6 + .../testing/constraints-3.9.txt | 6 + .../tests/__init__.py | 15 + .../tests/unit/__init__.py | 15 + .../tests/unit/gapic/__init__.py | 15 + .../gapic/parallelstore_v1beta/__init__.py | 15 + .../test_parallelstore.py | 6240 +++++++++++++++++ 68 files changed, 16603 insertions(+) create mode 100644 packages/google-cloud-parallelstore/.OwlBot.yaml create mode 100644 packages/google-cloud-parallelstore/.coveragerc create mode 100644 packages/google-cloud-parallelstore/.flake8 create mode 100644 packages/google-cloud-parallelstore/.gitignore create mode 100644 packages/google-cloud-parallelstore/.repo-metadata.json create mode 100644 packages/google-cloud-parallelstore/CHANGELOG.md create mode 100644 packages/google-cloud-parallelstore/CODE_OF_CONDUCT.md create mode 100644 packages/google-cloud-parallelstore/CONTRIBUTING.rst create mode 100644 packages/google-cloud-parallelstore/LICENSE create mode 100644 packages/google-cloud-parallelstore/MANIFEST.in create mode 100644 packages/google-cloud-parallelstore/README.rst create mode 120000 packages/google-cloud-parallelstore/docs/CHANGELOG.md create mode 120000 packages/google-cloud-parallelstore/docs/README.rst create mode 100644 packages/google-cloud-parallelstore/docs/_static/custom.css create mode 100644 packages/google-cloud-parallelstore/docs/_templates/layout.html create mode 100644 packages/google-cloud-parallelstore/docs/conf.py create mode 100644 packages/google-cloud-parallelstore/docs/index.rst create mode 100644 packages/google-cloud-parallelstore/docs/multiprocessing.rst create mode 100644 packages/google-cloud-parallelstore/docs/parallelstore_v1beta/parallelstore.rst create mode 100644 packages/google-cloud-parallelstore/docs/parallelstore_v1beta/services_.rst create mode 100644 packages/google-cloud-parallelstore/docs/parallelstore_v1beta/types_.rst create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore/__init__.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore/py.typed create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/__init__.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_metadata.json create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/py.typed create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/__init__.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/__init__.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/async_client.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/client.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/pagers.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/__init__.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/base.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/grpc.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/rest.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/types/__init__.py create mode 100644 packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/types/parallelstore.py create mode 100644 packages/google-cloud-parallelstore/mypy.ini create mode 100644 packages/google-cloud-parallelstore/noxfile.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_create_instance_async.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_create_instance_sync.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_delete_instance_async.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_delete_instance_sync.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_get_instance_async.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_get_instance_sync.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_list_instances_async.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_list_instances_sync.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_update_instance_async.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_update_instance_sync.py create mode 100644 packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1beta.json create mode 100755 packages/google-cloud-parallelstore/scripts/decrypt-secrets.sh create mode 100644 packages/google-cloud-parallelstore/scripts/fixup_parallelstore_v1beta_keywords.py create mode 100644 packages/google-cloud-parallelstore/setup.py create mode 100644 packages/google-cloud-parallelstore/testing/.gitignore create mode 100644 packages/google-cloud-parallelstore/testing/constraints-3.10.txt create mode 100644 packages/google-cloud-parallelstore/testing/constraints-3.11.txt create mode 100644 packages/google-cloud-parallelstore/testing/constraints-3.12.txt create mode 100644 packages/google-cloud-parallelstore/testing/constraints-3.7.txt create mode 100644 packages/google-cloud-parallelstore/testing/constraints-3.8.txt create mode 100644 packages/google-cloud-parallelstore/testing/constraints-3.9.txt create mode 100644 packages/google-cloud-parallelstore/tests/__init__.py create mode 100644 packages/google-cloud-parallelstore/tests/unit/__init__.py create mode 100644 packages/google-cloud-parallelstore/tests/unit/gapic/__init__.py create mode 100644 packages/google-cloud-parallelstore/tests/unit/gapic/parallelstore_v1beta/__init__.py create mode 100644 packages/google-cloud-parallelstore/tests/unit/gapic/parallelstore_v1beta/test_parallelstore.py diff --git a/packages/google-cloud-parallelstore/.OwlBot.yaml b/packages/google-cloud-parallelstore/.OwlBot.yaml new file mode 100644 index 000000000000..a6f6dd5d55da --- /dev/null +++ b/packages/google-cloud-parallelstore/.OwlBot.yaml @@ -0,0 +1,18 @@ +# Copyright 2022 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. + +deep-copy-regex: + - source: /google/cloud/parallelstore/(v.*)/.*-py + dest: /owl-bot-staging/google-cloud-parallelstore/$1 +api-name: google-cloud-parallelstore diff --git a/packages/google-cloud-parallelstore/.coveragerc b/packages/google-cloud-parallelstore/.coveragerc new file mode 100644 index 000000000000..18ae9360538f --- /dev/null +++ b/packages/google-cloud-parallelstore/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/parallelstore/__init__.py + google/cloud/parallelstore/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/packages/google-cloud-parallelstore/.flake8 b/packages/google-cloud-parallelstore/.flake8 new file mode 100644 index 000000000000..87f6e408c47d --- /dev/null +++ b/packages/google-cloud-parallelstore/.flake8 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2023 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. + +# Generated by synthtool. DO NOT EDIT! +[flake8] +ignore = E203, E231, E266, E501, W503 +exclude = + # Exclude generated code. + **/proto/** + **/gapic/** + **/services/** + **/types/** + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/packages/google-cloud-parallelstore/.gitignore b/packages/google-cloud-parallelstore/.gitignore new file mode 100644 index 000000000000..b4243ced74e4 --- /dev/null +++ b/packages/google-cloud-parallelstore/.gitignore @@ -0,0 +1,63 @@ +*.py[cod] +*.sw[op] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +.eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 +__pycache__ + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.nox +.cache +.pytest_cache + + +# Mac +.DS_Store + +# JetBrains +.idea + +# VS Code +.vscode + +# emacs +*~ + +# Built documentation +docs/_build +bigquery/docs/generated +docs.metadata + +# Virtual environment +env/ + +# Test logs +coverage.xml +*sponge_log.xml + +# System test environment variables. +system_tests/local_test_setup + +# Make sure a generated file isn't accidentally committed. +pylintrc +pylintrc.test diff --git a/packages/google-cloud-parallelstore/.repo-metadata.json b/packages/google-cloud-parallelstore/.repo-metadata.json new file mode 100644 index 000000000000..9ac7dfe0db3d --- /dev/null +++ b/packages/google-cloud-parallelstore/.repo-metadata.json @@ -0,0 +1,17 @@ +{ + "name": "google-cloud-parallelstore", + "name_pretty": "Parallelstore API", + "api_description": "Parallelstore is based on Intel DAOS and delivers up to 6.3x greater read throughput performance compared to competitive Lustre scratch offerings.", + "product_documentation": "https://cloud.google.com/parallelstore", + "client_documentation": "https://cloud.google.com/python/docs/reference/google-cloud-parallelstore/latest", + "issue_tracker": "https://github.com/googleapis/google-cloud-python/issues", + "release_level": "preview", + "language": "python", + "library_type": "GAPIC_AUTO", + "repo": "googleapis/google-cloud-python", + "distribution_name": "google-cloud-parallelstore", + "api_id": "parallelstore.googleapis.com", + "default_version": "v1beta", + "codeowner_team": "", + "api_shortname": "parallelstore" +} diff --git a/packages/google-cloud-parallelstore/CHANGELOG.md b/packages/google-cloud-parallelstore/CHANGELOG.md new file mode 100644 index 000000000000..5ddad421e08f --- /dev/null +++ b/packages/google-cloud-parallelstore/CHANGELOG.md @@ -0,0 +1 @@ +# Changelog \ No newline at end of file diff --git a/packages/google-cloud-parallelstore/CODE_OF_CONDUCT.md b/packages/google-cloud-parallelstore/CODE_OF_CONDUCT.md new file mode 100644 index 000000000000..039f43681204 --- /dev/null +++ b/packages/google-cloud-parallelstore/CODE_OF_CONDUCT.md @@ -0,0 +1,95 @@ + +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +This Code of Conduct also applies outside the project spaces when the Project +Steward has a reasonable belief that an individual's behavior may have a +negative impact on the project or its community. + +## Conflict Resolution + +We do not believe that all conflict is bad; healthy debate and disagreement +often yield positive results. However, it is never okay to be disrespectful or +to engage in behavior that violates the project’s code of conduct. + +If you see someone violating the code of conduct, you are encouraged to address +the behavior directly with those involved. Many issues can be resolved quickly +and easily, and this gives people more control over the outcome of their +dispute. If you are unable to resolve the matter for any reason, or if the +behavior is threatening or harassing, report it. We are dedicated to providing +an environment where participants feel welcome and safe. + + +Reports should be directed to *googleapis-stewards@google.com*, the +Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to +receive and address reported violations of the code of conduct. They will then +work with a committee consisting of representatives from the Open Source +Programs Office and the Google Open Source Strategy team. If for any reason you +are uncomfortable reaching out to the Project Steward, please email +opensource@google.com. + +We will investigate every complaint, but you may not receive a direct response. +We will use our discretion in determining when and how to follow up on reported +incidents, which may range from not taking action to permanent expulsion from +the project and project-sponsored spaces. We will notify the accused of the +report and provide them an opportunity to discuss it before any action is taken. +The identity of the reporter will be omitted from the details of the report +supplied to the accused. In potentially harmful situations, such as ongoing +harassment or threats to anyone's safety, we may take action without notice. + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at +https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/packages/google-cloud-parallelstore/CONTRIBUTING.rst b/packages/google-cloud-parallelstore/CONTRIBUTING.rst new file mode 100644 index 000000000000..7ccb06b1d947 --- /dev/null +++ b/packages/google-cloud-parallelstore/CONTRIBUTING.rst @@ -0,0 +1,271 @@ +.. Generated by synthtool. DO NOT EDIT! +############ +Contributing +############ + +#. **Please sign one of the contributor license agreements below.** +#. Fork the repo, develop and test your code changes, add docs. +#. Make sure that your commit messages clearly describe the changes. +#. Send a pull request. (Please Read: `Faster Pull Request Reviews`_) + +.. _Faster Pull Request Reviews: https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#best-practices-for-faster-reviews + +.. contents:: Here are some guidelines for hacking on the Google Cloud Client libraries. + +*************** +Adding Features +*************** + +In order to add a feature: + +- The feature must be documented in both the API and narrative + documentation. + +- The feature must work fully on the following CPython versions: + 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 on both UNIX and Windows. + +- The feature must not add unnecessary dependencies (where + "unnecessary" is of course subjective, but new dependencies should + be discussed). + +**************************** +Using a Development Checkout +**************************** + +You'll have to create a development environment using a Git checkout: + +- While logged into your GitHub account, navigate to the + ``google-cloud-python`` `repo`_ on GitHub. + +- Fork and clone the ``google-cloud-python`` repository to your GitHub account by + clicking the "Fork" button. + +- Clone your fork of ``google-cloud-python`` from your GitHub account to your local + computer, substituting your account username and specifying the destination + as ``hack-on-google-cloud-python``. E.g.:: + + $ cd ${HOME} + $ git clone git@github.com:USERNAME/google-cloud-python.git hack-on-google-cloud-python + $ cd hack-on-google-cloud-python + # Configure remotes such that you can pull changes from the googleapis/google-cloud-python + # repository into your local repository. + $ git remote add upstream git@github.com:googleapis/google-cloud-python.git + # fetch and merge changes from upstream into main + $ git fetch upstream + $ git merge upstream/main + +Now your local repo is set up such that you will push changes to your GitHub +repo, from which you can submit a pull request. + +To work on the codebase and run the tests, we recommend using ``nox``, +but you can also use a ``virtualenv`` of your own creation. + +.. _repo: https://github.com/googleapis/google-cloud-python + +Using ``nox`` +============= + +We use `nox `__ to instrument our tests. + +- To test your changes, run unit tests with ``nox``:: + $ nox -s unit + +- To run a single unit test:: + + $ nox -s unit-3.12 -- -k + + + .. note:: + + The unit tests and system tests are described in the + ``noxfile.py`` files in each directory. + +.. nox: https://pypi.org/project/nox/ + +***************************************** +I'm getting weird errors... Can you help? +***************************************** + +If the error mentions ``Python.h`` not being found, +install ``python-dev`` and try again. +On Debian/Ubuntu:: + + $ sudo apt-get install python-dev + +************ +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 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:: + + $ nox -s lint + +- In order to make ``nox -s lint`` run faster, you can set some environment + variables:: + + export GOOGLE_CLOUD_TESTING_REMOTE="upstream" + export GOOGLE_CLOUD_TESTING_BRANCH="main" + + By doing this, you are specifying the location of the most up-to-date + version of ``google-cloud-python``. The + remote name ``upstream`` should point to the official ``googleapis`` + checkout and the branch should be the default branch on that remote (``main``). + +- This repository contains configuration for the + `pre-commit `__ tool, which automates checking + our linters during a commit. If you have it installed on your ``$PATH``, + you can enable enforcing those checks via: + +.. code-block:: bash + + $ pre-commit install + pre-commit installed at .git/hooks/pre-commit + +Exceptions to PEP8: + +- Many unit tests use a helper method, ``_call_fut`` ("FUT" is short for + "Function-Under-Test"), which is PEP8-incompliant, but more readable. + Some also use a local variable, ``MUT`` (short for "Module-Under-Test"). + +******************** +Running System Tests +******************** + +- To run system tests, you can execute:: + + # Run all system tests + $ nox -s system + + # Run a single system test + $ nox -s system-3.12 -- -k + + + .. note:: + + System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11 and 3.12. + 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 + auth settings and change some configuration in your project to + run all the tests. + +- System tests will be run against an actual project. You should use local credentials from gcloud when possible. See `Best practices for application authentication `__. Some tests require a service account. For those tests see `Authenticating as a service account `__. + +************* +Test Coverage +************* + +- The codebase *must* have 100% test statement coverage after each commit. + You can test coverage via ``nox -s cover``. + +****************************************************** +Documentation Coverage and Building HTML Documentation +****************************************************** + +If you fix a bug, and the bug requires an API or behavior modification, all +documentation in this package which references that API or behavior must be +changed to reflect the bug fix, ideally in the same commit that fixes the bug +or adds the feature. + +Build the docs via: + + $ nox -s docs + +************************* +Samples and code snippets +************************* + +Code samples and snippets live in the `samples/` catalogue. Feel free to +provide more examples, but make sure to write tests for those examples. +Each folder containing example code requires its own `noxfile.py` script +which automates testing. If you decide to create a new folder, you can +base it on the `samples/snippets` folder (providing `noxfile.py` and +the requirements files). + +The tests will run against a real Google Cloud Project, so you should +configure them just like the System Tests. + +- To run sample tests, you can execute:: + + # Run all tests in a folder + $ cd samples/snippets + $ nox -s py-3.8 + + # Run a single sample test + $ cd samples/snippets + $ nox -s py-3.8 -- -k + +******************************************** +Note About ``README`` as it pertains to PyPI +******************************************** + +The `description on PyPI`_ for the project comes directly from the +``README``. Due to the reStructuredText (``rst``) parser used by +PyPI, relative links which will work on GitHub (e.g. ``CONTRIBUTING.rst`` +instead of +``https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst``) +may cause problems creating links or rendering the description. + +.. _description on PyPI: https://pypi.org/project/google-cloud-parallelstore + + +************************* +Supported Python Versions +************************* + +We support: + +- `Python 3.7`_ +- `Python 3.8`_ +- `Python 3.9`_ +- `Python 3.10`_ +- `Python 3.11`_ +- `Python 3.12`_ + +.. _Python 3.7: https://docs.python.org/3.7/ +.. _Python 3.8: https://docs.python.org/3.8/ +.. _Python 3.9: https://docs.python.org/3.9/ +.. _Python 3.10: https://docs.python.org/3.10/ +.. _Python 3.11: https://docs.python.org/3.11/ +.. _Python 3.12: https://docs.python.org/3.12/ + + +Supported versions can be found in our ``noxfile.py`` `config`_. + +.. _config: https://github.com/googleapis/google-cloud-python/blob/main/packages/google-cloud-parallelstore/noxfile.py + + +********** +Versioning +********** + +This library follows `Semantic Versioning`_. + +.. _Semantic Versioning: http://semver.org/ + +Some packages are currently in major version zero (``0.y.z``), which means that +anything may change at any time and the public API should not be considered +stable. + +****************************** +Contributor License Agreements +****************************** + +Before we can accept your pull requests you'll need to sign a Contributor +License Agreement (CLA): + +- **If you are an individual writing original source code** and **you own the + intellectual property**, then you'll need to sign an + `individual CLA `__. +- **If you work for a company that wants to allow you to contribute your work**, + then you'll need to sign a + `corporate CLA `__. + +You can sign these electronically (just scroll to the bottom). After that, +we'll be able to accept your pull requests. diff --git a/packages/google-cloud-parallelstore/LICENSE b/packages/google-cloud-parallelstore/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/packages/google-cloud-parallelstore/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/packages/google-cloud-parallelstore/MANIFEST.in b/packages/google-cloud-parallelstore/MANIFEST.in new file mode 100644 index 000000000000..e0a66705318e --- /dev/null +++ b/packages/google-cloud-parallelstore/MANIFEST.in @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2023 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. + +# Generated by synthtool. DO NOT EDIT! +include README.rst LICENSE +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 diff --git a/packages/google-cloud-parallelstore/README.rst b/packages/google-cloud-parallelstore/README.rst new file mode 100644 index 000000000000..f23c1253c0bb --- /dev/null +++ b/packages/google-cloud-parallelstore/README.rst @@ -0,0 +1,108 @@ +Python Client for Parallelstore API +=================================== + +|preview| |pypi| |versions| + +`Parallelstore API`_: Parallelstore is based on Intel DAOS and delivers up to 6.3x greater read throughput performance compared to competitive Lustre scratch offerings. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-cloud-parallelstore.svg + :target: https://pypi.org/project/google-cloud-parallelstore/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-parallelstore.svg + :target: https://pypi.org/project/google-cloud-parallelstore/ +.. _Parallelstore API: https://cloud.google.com/parallelstore +.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/google-cloud-parallelstore/latest +.. _Product Documentation: https://cloud.google.com/parallelstore + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. `Enable the Parallelstore API.`_ +4. `Setup Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Enable the Parallelstore API.: https://cloud.google.com/parallelstore +.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-parallelstore/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.7 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.6 + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-cloud-parallelstore + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-cloud-parallelstore + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Parallelstore API + to see other available methods on the client. +- Read the `Parallelstore API Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Parallelstore API Product documentation: https://cloud.google.com/parallelstore +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst diff --git a/packages/google-cloud-parallelstore/docs/CHANGELOG.md b/packages/google-cloud-parallelstore/docs/CHANGELOG.md new file mode 120000 index 000000000000..04c99a55caae --- /dev/null +++ b/packages/google-cloud-parallelstore/docs/CHANGELOG.md @@ -0,0 +1 @@ +../CHANGELOG.md \ No newline at end of file diff --git a/packages/google-cloud-parallelstore/docs/README.rst b/packages/google-cloud-parallelstore/docs/README.rst new file mode 120000 index 000000000000..89a0106941ff --- /dev/null +++ b/packages/google-cloud-parallelstore/docs/README.rst @@ -0,0 +1 @@ +../README.rst \ No newline at end of file diff --git a/packages/google-cloud-parallelstore/docs/_static/custom.css b/packages/google-cloud-parallelstore/docs/_static/custom.css new file mode 100644 index 000000000000..b0a295464b23 --- /dev/null +++ b/packages/google-cloud-parallelstore/docs/_static/custom.css @@ -0,0 +1,20 @@ +div#python2-eol { + border-color: red; + border-width: medium; +} + +/* Ensure minimum width for 'Parameters' / 'Returns' column */ +dl.field-list > dt { + min-width: 100px +} + +/* Insert space between methods for readability */ +dl.method { + padding-top: 10px; + padding-bottom: 10px +} + +/* Insert empty space between classes */ +dl.class { + padding-bottom: 50px +} diff --git a/packages/google-cloud-parallelstore/docs/_templates/layout.html b/packages/google-cloud-parallelstore/docs/_templates/layout.html new file mode 100644 index 000000000000..6316a537f72b --- /dev/null +++ b/packages/google-cloud-parallelstore/docs/_templates/layout.html @@ -0,0 +1,50 @@ + +{% extends "!layout.html" %} +{%- block content %} +{%- if theme_fixed_sidebar|lower == 'true' %} +
+ {{ sidebar() }} + {%- block document %} +
+ {%- if render_sidebar %} +
+ {%- endif %} + + {%- block relbar_top %} + {%- if theme_show_relbar_top|tobool %} + + {%- endif %} + {% endblock %} + +
+
+ As of January 1, 2020 this library no longer supports Python 2 on the latest released version. + Library versions released prior to that date will continue to be available. For more information please + visit Python 2 support on Google Cloud. +
+ {% block body %} {% endblock %} +
+ + {%- block relbar_bottom %} + {%- if theme_show_relbar_bottom|tobool %} + + {%- endif %} + {% endblock %} + + {%- if render_sidebar %} +
+ {%- endif %} +
+ {%- endblock %} +
+
+{%- else %} +{{ super() }} +{%- endif %} +{%- endblock %} diff --git a/packages/google-cloud-parallelstore/docs/conf.py b/packages/google-cloud-parallelstore/docs/conf.py new file mode 100644 index 000000000000..92d443638c21 --- /dev/null +++ b/packages/google-cloud-parallelstore/docs/conf.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# google-cloud-parallelstore documentation build configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import os +import shlex +import sys + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath("..")) + +# For plugins that can not read conf.py. +# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85 +sys.path.insert(0, os.path.abspath(".")) + +__version__ = "" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "1.5.5" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "sphinx.ext.coverage", + "sphinx.ext.doctest", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "recommonmark", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_options = {"members": True} +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = "google-cloud-parallelstore" +copyright = "2019, Google" +author = "Google APIs" + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = __version__ +# The short X.Y version. +version = ".".join(release.split(".")[0:2]) + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [ + "_build", + "**/.nox/**/*", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/snippets/README.rst", +] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + "description": "Google Cloud Client Libraries for google-cloud-parallelstore", + "github_user": "googleapis", + "github_repo": "google-cloud-python", + "github_banner": True, + "font_family": "'Roboto', Georgia, sans", + "head_font_family": "'Roboto', Georgia, serif", + "code_font_family": "'Roboto Mono', 'Consolas', monospace", +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = "google-cloud-parallelstore-doc" + +# -- Options for warnings ------------------------------------------------------ + + +suppress_warnings = [ + # Temporarily suppress this to avoid "more than one target found for + # cross-reference" warning, which are intractable for us to avoid while in + # a mono-repo. + # See https://github.com/sphinx-doc/sphinx/blob + # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 + "ref.python" +] + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Latex figure (float) alignment + #'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + root_doc, + "google-cloud-parallelstore.tex", + "google-cloud-parallelstore Documentation", + author, + "manual", + ) +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + root_doc, + "google-cloud-parallelstore", + "google-cloud-parallelstore Documentation", + [author], + 1, + ) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + root_doc, + "google-cloud-parallelstore", + "google-cloud-parallelstore Documentation", + author, + "google-cloud-parallelstore", + "google-cloud-parallelstore Library", + "APIs", + ) +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("https://python.readthedocs.org/en/latest/", None), + "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), + "google.api_core": ( + "https://googleapis.dev/python/google-api-core/latest/", + None, + ), + "grpc": ("https://grpc.github.io/grpc/python/", None), + "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# Napoleon settings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True diff --git a/packages/google-cloud-parallelstore/docs/index.rst b/packages/google-cloud-parallelstore/docs/index.rst new file mode 100644 index 000000000000..4657e75774a9 --- /dev/null +++ b/packages/google-cloud-parallelstore/docs/index.rst @@ -0,0 +1,23 @@ +.. include:: README.rst + +.. include:: multiprocessing.rst + + +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + parallelstore_v1beta/services_ + parallelstore_v1beta/types_ + + +Changelog +--------- + +For a list of all ``google-cloud-parallelstore`` releases: + +.. toctree:: + :maxdepth: 2 + + CHANGELOG diff --git a/packages/google-cloud-parallelstore/docs/multiprocessing.rst b/packages/google-cloud-parallelstore/docs/multiprocessing.rst new file mode 100644 index 000000000000..536d17b2ea65 --- /dev/null +++ b/packages/google-cloud-parallelstore/docs/multiprocessing.rst @@ -0,0 +1,7 @@ +.. note:: + + Because this client uses :mod:`grpc` library, it is safe to + share instances across threads. In multiprocessing scenarios, the best + practice is to create client instances *after* the invocation of + :func:`os.fork` by :class:`multiprocessing.pool.Pool` or + :class:`multiprocessing.Process`. diff --git a/packages/google-cloud-parallelstore/docs/parallelstore_v1beta/parallelstore.rst b/packages/google-cloud-parallelstore/docs/parallelstore_v1beta/parallelstore.rst new file mode 100644 index 000000000000..82e8b6507690 --- /dev/null +++ b/packages/google-cloud-parallelstore/docs/parallelstore_v1beta/parallelstore.rst @@ -0,0 +1,10 @@ +Parallelstore +------------------------------- + +.. automodule:: google.cloud.parallelstore_v1beta.services.parallelstore + :members: + :inherited-members: + +.. automodule:: google.cloud.parallelstore_v1beta.services.parallelstore.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-parallelstore/docs/parallelstore_v1beta/services_.rst b/packages/google-cloud-parallelstore/docs/parallelstore_v1beta/services_.rst new file mode 100644 index 000000000000..22671c2edf73 --- /dev/null +++ b/packages/google-cloud-parallelstore/docs/parallelstore_v1beta/services_.rst @@ -0,0 +1,6 @@ +Services for Google Cloud Parallelstore v1beta API +================================================== +.. toctree:: + :maxdepth: 2 + + parallelstore diff --git a/packages/google-cloud-parallelstore/docs/parallelstore_v1beta/types_.rst b/packages/google-cloud-parallelstore/docs/parallelstore_v1beta/types_.rst new file mode 100644 index 000000000000..4fd25f03a091 --- /dev/null +++ b/packages/google-cloud-parallelstore/docs/parallelstore_v1beta/types_.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Parallelstore v1beta API +=============================================== + +.. automodule:: google.cloud.parallelstore_v1beta.types + :members: + :show-inheritance: diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore/__init__.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore/__init__.py new file mode 100644 index 000000000000..66e8f4147492 --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore/__init__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from google.cloud.parallelstore import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.parallelstore_v1beta.services.parallelstore.async_client import ( + ParallelstoreAsyncClient, +) +from google.cloud.parallelstore_v1beta.services.parallelstore.client import ( + ParallelstoreClient, +) +from google.cloud.parallelstore_v1beta.types.parallelstore import ( + CreateInstanceRequest, + DeleteInstanceRequest, + GetInstanceRequest, + Instance, + ListInstancesRequest, + ListInstancesResponse, + OperationMetadata, + UpdateInstanceRequest, +) + +__all__ = ( + "ParallelstoreClient", + "ParallelstoreAsyncClient", + "CreateInstanceRequest", + "DeleteInstanceRequest", + "GetInstanceRequest", + "Instance", + "ListInstancesRequest", + "ListInstancesResponse", + "OperationMetadata", + "UpdateInstanceRequest", +) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py new file mode 100644 index 000000000000..360a0d13ebdd --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore/py.typed b/packages/google-cloud-parallelstore/google/cloud/parallelstore/py.typed new file mode 100644 index 000000000000..743160d56b7b --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-parallelstore package uses inline types. diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/__init__.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/__init__.py new file mode 100644 index 000000000000..3e6f336fcdbf --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/__init__.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from google.cloud.parallelstore_v1beta import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.parallelstore import ParallelstoreAsyncClient, ParallelstoreClient +from .types.parallelstore import ( + CreateInstanceRequest, + DeleteInstanceRequest, + GetInstanceRequest, + Instance, + ListInstancesRequest, + ListInstancesResponse, + OperationMetadata, + UpdateInstanceRequest, +) + +__all__ = ( + "ParallelstoreAsyncClient", + "CreateInstanceRequest", + "DeleteInstanceRequest", + "GetInstanceRequest", + "Instance", + "ListInstancesRequest", + "ListInstancesResponse", + "OperationMetadata", + "ParallelstoreClient", + "UpdateInstanceRequest", +) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_metadata.json b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_metadata.json new file mode 100644 index 000000000000..4548b04b30a7 --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_metadata.json @@ -0,0 +1,103 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.parallelstore_v1beta", + "protoPackage": "google.cloud.parallelstore.v1beta", + "schema": "1.0", + "services": { + "Parallelstore": { + "clients": { + "grpc": { + "libraryClient": "ParallelstoreClient", + "rpcs": { + "CreateInstance": { + "methods": [ + "create_instance" + ] + }, + "DeleteInstance": { + "methods": [ + "delete_instance" + ] + }, + "GetInstance": { + "methods": [ + "get_instance" + ] + }, + "ListInstances": { + "methods": [ + "list_instances" + ] + }, + "UpdateInstance": { + "methods": [ + "update_instance" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ParallelstoreAsyncClient", + "rpcs": { + "CreateInstance": { + "methods": [ + "create_instance" + ] + }, + "DeleteInstance": { + "methods": [ + "delete_instance" + ] + }, + "GetInstance": { + "methods": [ + "get_instance" + ] + }, + "ListInstances": { + "methods": [ + "list_instances" + ] + }, + "UpdateInstance": { + "methods": [ + "update_instance" + ] + } + } + }, + "rest": { + "libraryClient": "ParallelstoreClient", + "rpcs": { + "CreateInstance": { + "methods": [ + "create_instance" + ] + }, + "DeleteInstance": { + "methods": [ + "delete_instance" + ] + }, + "GetInstance": { + "methods": [ + "get_instance" + ] + }, + "ListInstances": { + "methods": [ + "list_instances" + ] + }, + "UpdateInstance": { + "methods": [ + "update_instance" + ] + } + } + } + } + } + } +} diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py new file mode 100644 index 000000000000..360a0d13ebdd --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/py.typed b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/py.typed new file mode 100644 index 000000000000..743160d56b7b --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-parallelstore package uses inline types. diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/__init__.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/__init__.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/__init__.py new file mode 100644 index 000000000000..47e73b987a21 --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from .async_client import ParallelstoreAsyncClient +from .client import ParallelstoreClient + +__all__ = ( + "ParallelstoreClient", + "ParallelstoreAsyncClient", +) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/async_client.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/async_client.py new file mode 100644 index 000000000000..4b9829150fe5 --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/async_client.py @@ -0,0 +1,1281 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from collections import OrderedDict +import functools +import re +from typing import ( + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.parallelstore_v1beta import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.parallelstore_v1beta.services.parallelstore import pagers +from google.cloud.parallelstore_v1beta.types import parallelstore + +from .client import ParallelstoreClient +from .transports.base import DEFAULT_CLIENT_INFO, ParallelstoreTransport +from .transports.grpc_asyncio import ParallelstoreGrpcAsyncIOTransport + + +class ParallelstoreAsyncClient: + """Service describing handlers for resources Configures and manages + parallelstore resources. + + Parallelstore service. + + The ``parallelstore.googleapis.com`` service implements the + parallelstore API and defines the following resource model for + managing instances: + + - The service works with a collection of cloud projects, named: + ``/projects/*`` + - Each project has a collection of available locations, named: + ``/locations/*`` + - Each location has a collection of instances named + ``/instances/*``. + - Parallelstore instances are resources of the form: + ``/projects/{project_id}/locations/{location_id}/instances/{instance_id}`` + + Note that location_id must be a Google Cloud ``zone``; for example: + + - ``projects/12345/locations/us-central1-c/instances/my-parallelstore-share`` + """ + + _client: ParallelstoreClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ParallelstoreClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ParallelstoreClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ParallelstoreClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = ParallelstoreClient._DEFAULT_UNIVERSE + + address_path = staticmethod(ParallelstoreClient.address_path) + parse_address_path = staticmethod(ParallelstoreClient.parse_address_path) + instance_path = staticmethod(ParallelstoreClient.instance_path) + parse_instance_path = staticmethod(ParallelstoreClient.parse_instance_path) + network_path = staticmethod(ParallelstoreClient.network_path) + parse_network_path = staticmethod(ParallelstoreClient.parse_network_path) + common_billing_account_path = staticmethod( + ParallelstoreClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ParallelstoreClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(ParallelstoreClient.common_folder_path) + parse_common_folder_path = staticmethod( + ParallelstoreClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ParallelstoreClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ParallelstoreClient.parse_common_organization_path + ) + common_project_path = staticmethod(ParallelstoreClient.common_project_path) + parse_common_project_path = staticmethod( + ParallelstoreClient.parse_common_project_path + ) + common_location_path = staticmethod(ParallelstoreClient.common_location_path) + parse_common_location_path = staticmethod( + ParallelstoreClient.parse_common_location_path + ) + + @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: + ParallelstoreAsyncClient: The constructed client. + """ + return ParallelstoreClient.from_service_account_info.__func__(ParallelstoreAsyncClient, 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: + ParallelstoreAsyncClient: The constructed client. + """ + return ParallelstoreClient.from_service_account_file.__func__(ParallelstoreAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ParallelstoreClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ParallelstoreTransport: + """Returns the transport used by the client instance. + + Returns: + ParallelstoreTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = functools.partial( + type(ParallelstoreClient).get_transport_class, type(ParallelstoreClient) + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ParallelstoreTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the parallelstore async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + 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, ~.ParallelstoreTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ParallelstoreClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def list_instances( + self, + request: Optional[Union[parallelstore.ListInstancesRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListInstancesAsyncPager: + r"""Lists Instances in a given project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import parallelstore_v1beta + + async def sample_list_instances(): + # Create a client + client = parallelstore_v1beta.ParallelstoreAsyncClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.ListInstancesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_instances(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.parallelstore_v1beta.types.ListInstancesRequest, dict]]): + The request object. Message for requesting list of + Instances + parent (:class:`str`): + Required. The project and location for which to retrieve + instance information, in the format + ``projects/{project_id}/locations/{location}``. For + Parallelstore locations map to Google Cloud zones, for + example **us-central1-a**. To retrieve instance + information for all locations, use "-" for the + ``{location}`` value. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.parallelstore_v1beta.services.parallelstore.pagers.ListInstancesAsyncPager: + Message for response to listing + Instances + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = parallelstore.ListInstancesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_instances, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListInstancesAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_instance( + self, + request: Optional[Union[parallelstore.GetInstanceRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> parallelstore.Instance: + r"""Gets details of a single Instance. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import parallelstore_v1beta + + async def sample_get_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreAsyncClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.GetInstanceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_instance(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.parallelstore_v1beta.types.GetInstanceRequest, dict]]): + The request object. Request to get an instance's details. + name (:class:`str`): + Required. The instance resource name, in the format + ``projects/{project_id}/locations/{location}/instances/{instance_id}``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.parallelstore_v1beta.types.Instance: + A Parallelstore instance. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = parallelstore.GetInstanceRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_instance, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_instance( + self, + request: Optional[Union[parallelstore.CreateInstanceRequest, dict]] = None, + *, + parent: Optional[str] = None, + instance: Optional[parallelstore.Instance] = None, + instance_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a Parallelstore instance in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import parallelstore_v1beta + + async def sample_create_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreAsyncClient() + + # Initialize request argument(s) + instance = parallelstore_v1beta.Instance() + instance.capacity_gib = 1247 + + request = parallelstore_v1beta.CreateInstanceRequest( + parent="parent_value", + instance_id="instance_id_value", + instance=instance, + ) + + # Make the request + operation = client.create_instance(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.parallelstore_v1beta.types.CreateInstanceRequest, dict]]): + The request object. Request for + [CreateInstance][google.cloud.parallelstore.v1beta.Parallelstore.CreateInstance] + parent (:class:`str`): + Required. The instance's project and location, in the + format ``projects/{project}/locations/{location}``. + Locations map to Google Cloud zones, for example + **us-west1-b**. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + instance (:class:`google.cloud.parallelstore_v1beta.types.Instance`): + Required. The instance to create. + This corresponds to the ``instance`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + instance_id (:class:`str`): + Required. The logical name of the Parallelstore instance + in the user project with the following restrictions: + + - Must contain only lowercase letters, numbers, and + hyphens. + - Must start with a letter. + - Must be between 1-63 characters. + - Must end with a number or a letter. + - Must be unique within the customer project / location + + This corresponds to the ``instance_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.parallelstore_v1beta.types.Instance` + A Parallelstore instance. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, instance, instance_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = parallelstore.CreateInstanceRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if instance is not None: + request.instance = instance + if instance_id is not None: + request.instance_id = instance_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_instance, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + parallelstore.Instance, + metadata_type=parallelstore.OperationMetadata, + ) + + # Done; return the response. + return response + + async def update_instance( + self, + request: Optional[Union[parallelstore.UpdateInstanceRequest, dict]] = None, + *, + instance: Optional[parallelstore.Instance] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates the parameters of a single Instance. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import parallelstore_v1beta + + async def sample_update_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreAsyncClient() + + # Initialize request argument(s) + instance = parallelstore_v1beta.Instance() + instance.capacity_gib = 1247 + + request = parallelstore_v1beta.UpdateInstanceRequest( + instance=instance, + ) + + # Make the request + operation = client.update_instance(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.parallelstore_v1beta.types.UpdateInstanceRequest, dict]]): + The request object. Message for updating a Instance + instance (:class:`google.cloud.parallelstore_v1beta.types.Instance`): + Required. The instance to update + This corresponds to the ``instance`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Required. Mask of fields to update .Field mask is used + to specify the fields to be overwritten in the Instance + resource by the update. At least one path must be + supplied in this field. The fields specified in the + update_mask are relative to the resource, not the full + request. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.parallelstore_v1beta.types.Instance` + A Parallelstore instance. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([instance, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = parallelstore.UpdateInstanceRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if instance is not None: + request.instance = instance + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_instance, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("instance.name", request.instance.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + parallelstore.Instance, + metadata_type=parallelstore.OperationMetadata, + ) + + # Done; return the response. + return response + + async def delete_instance( + self, + request: Optional[Union[parallelstore.DeleteInstanceRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a single Instance. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import parallelstore_v1beta + + async def sample_delete_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreAsyncClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.DeleteInstanceRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_instance(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.parallelstore_v1beta.types.DeleteInstanceRequest, dict]]): + The request object. Message for deleting a Instance + name (:class:`str`): + Required. Name of the resource + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = parallelstore.DeleteInstanceRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_instance, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=parallelstore.OperationMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` 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): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # 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): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_operation( + self, + request: Optional[operations_pb2.DeleteOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a long-running operation. + + This method indicates that the client is no longer interested + in the operation result. It does not cancel the operation. + If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # 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): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # 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): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.cancel_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.location_pb2.Location: + Location object. + """ + # 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): + request = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_location, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` 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): + request = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_locations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ParallelstoreAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +__all__ = ("ParallelstoreAsyncClient",) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/client.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/client.py new file mode 100644 index 000000000000..d80af52675f4 --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/client.py @@ -0,0 +1,1736 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from collections import OrderedDict +import os +import re +from typing import ( + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.parallelstore_v1beta import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.parallelstore_v1beta.services.parallelstore import pagers +from google.cloud.parallelstore_v1beta.types import parallelstore + +from .transports.base import DEFAULT_CLIENT_INFO, ParallelstoreTransport +from .transports.grpc import ParallelstoreGrpcTransport +from .transports.grpc_asyncio import ParallelstoreGrpcAsyncIOTransport +from .transports.rest import ParallelstoreRestTransport + + +class ParallelstoreClientMeta(type): + """Metaclass for the Parallelstore client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = OrderedDict() # type: Dict[str, Type[ParallelstoreTransport]] + _transport_registry["grpc"] = ParallelstoreGrpcTransport + _transport_registry["grpc_asyncio"] = ParallelstoreGrpcAsyncIOTransport + _transport_registry["rest"] = ParallelstoreRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ParallelstoreTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ParallelstoreClient(metaclass=ParallelstoreClientMeta): + """Service describing handlers for resources Configures and manages + parallelstore resources. + + Parallelstore service. + + The ``parallelstore.googleapis.com`` service implements the + parallelstore API and defines the following resource model for + managing instances: + + - The service works with a collection of cloud projects, named: + ``/projects/*`` + - Each project has a collection of available locations, named: + ``/locations/*`` + - Each location has a collection of instances named + ``/instances/*``. + - Parallelstore instances are resources of the form: + ``/projects/{project_id}/locations/{location_id}/instances/{instance_id}`` + + Note that location_id must be a Google Cloud ``zone``; for example: + + - ``projects/12345/locations/us-central1-c/instances/my-parallelstore-share`` + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "parallelstore.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "parallelstore.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @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: + ParallelstoreClient: 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 + 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: + ParallelstoreClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ParallelstoreTransport: + """Returns the transport used by the client instance. + + Returns: + ParallelstoreTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def address_path( + project: str, + region: str, + address: str, + ) -> str: + """Returns a fully-qualified address string.""" + return "projects/{project}/regions/{region}/addresses/{address}".format( + project=project, + region=region, + address=address, + ) + + @staticmethod + def parse_address_path(path: str) -> Dict[str, str]: + """Parses a address path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/regions/(?P.+?)/addresses/(?P
.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def instance_path( + project: str, + location: str, + instance: str, + ) -> str: + """Returns a fully-qualified instance string.""" + return "projects/{project}/locations/{location}/instances/{instance}".format( + project=project, + location=location, + instance=instance, + ) + + @staticmethod + def parse_instance_path(path: str) -> Dict[str, str]: + """Parses a instance path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/instances/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + project: str, + network: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "projects/{project}/global/networks/{network}".format( + project=project, + network=network, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/global/networks/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ParallelstoreClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ParallelstoreClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ParallelstoreClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ParallelstoreClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + @staticmethod + def _compare_universes( + client_universe: str, credentials: ga_credentials.Credentials + ) -> bool: + """Returns True iff the universe domains used by the client and credentials match. + + Args: + client_universe (str): The universe domain configured via the client options. + credentials (ga_credentials.Credentials): The credentials being used in the client. + + Returns: + bool: True iff client_universe matches the universe in credentials. + + Raises: + ValueError: when client_universe does not match the universe in credentials. + """ + + default_universe = ParallelstoreClient._DEFAULT_UNIVERSE + credentials_universe = getattr(credentials, "universe_domain", default_universe) + + if client_universe != credentials_universe: + raise ValueError( + "The configured universe domain " + f"({client_universe}) does not match the universe domain " + f"found in the credentials ({credentials_universe}). " + "If you haven't configured the universe domain explicitly, " + f"`{default_universe}` is the default." + ) + return True + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + self._is_universe_domain_valid = ( + self._is_universe_domain_valid + or ParallelstoreClient._compare_universes( + self.universe_domain, self.transport._credentials + ) + ) + return self._is_universe_domain_valid + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ParallelstoreTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the parallelstore client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + 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, ParallelstoreTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ParallelstoreClient._read_environment_variables() + self._client_cert_source = ParallelstoreClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = ParallelstoreClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + api_key_value = getattr(self._client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, ParallelstoreTransport) + if transport_provided: + # transport is a ParallelstoreTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(ParallelstoreTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ParallelstoreClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + Transport = type(self).get_transport_class(cast(str, transport)) + self._transport = Transport( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + def list_instances( + self, + request: Optional[Union[parallelstore.ListInstancesRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListInstancesPager: + r"""Lists Instances in a given project and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import parallelstore_v1beta + + def sample_list_instances(): + # Create a client + client = parallelstore_v1beta.ParallelstoreClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.ListInstancesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_instances(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.parallelstore_v1beta.types.ListInstancesRequest, dict]): + The request object. Message for requesting list of + Instances + parent (str): + Required. The project and location for which to retrieve + instance information, in the format + ``projects/{project_id}/locations/{location}``. For + Parallelstore locations map to Google Cloud zones, for + example **us-central1-a**. To retrieve instance + information for all locations, use "-" for the + ``{location}`` value. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.parallelstore_v1beta.services.parallelstore.pagers.ListInstancesPager: + Message for response to listing + Instances + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a parallelstore.ListInstancesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, parallelstore.ListInstancesRequest): + request = parallelstore.ListInstancesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_instances] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListInstancesPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_instance( + self, + request: Optional[Union[parallelstore.GetInstanceRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> parallelstore.Instance: + r"""Gets details of a single Instance. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import parallelstore_v1beta + + def sample_get_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.GetInstanceRequest( + name="name_value", + ) + + # Make the request + response = client.get_instance(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.parallelstore_v1beta.types.GetInstanceRequest, dict]): + The request object. Request to get an instance's details. + name (str): + Required. The instance resource name, in the format + ``projects/{project_id}/locations/{location}/instances/{instance_id}``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.parallelstore_v1beta.types.Instance: + A Parallelstore instance. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a parallelstore.GetInstanceRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, parallelstore.GetInstanceRequest): + request = parallelstore.GetInstanceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_instance] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_instance( + self, + request: Optional[Union[parallelstore.CreateInstanceRequest, dict]] = None, + *, + parent: Optional[str] = None, + instance: Optional[parallelstore.Instance] = None, + instance_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Creates a Parallelstore instance in a given project + and location. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import parallelstore_v1beta + + def sample_create_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreClient() + + # Initialize request argument(s) + instance = parallelstore_v1beta.Instance() + instance.capacity_gib = 1247 + + request = parallelstore_v1beta.CreateInstanceRequest( + parent="parent_value", + instance_id="instance_id_value", + instance=instance, + ) + + # Make the request + operation = client.create_instance(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.parallelstore_v1beta.types.CreateInstanceRequest, dict]): + The request object. Request for + [CreateInstance][google.cloud.parallelstore.v1beta.Parallelstore.CreateInstance] + parent (str): + Required. The instance's project and location, in the + format ``projects/{project}/locations/{location}``. + Locations map to Google Cloud zones, for example + **us-west1-b**. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + instance (google.cloud.parallelstore_v1beta.types.Instance): + Required. The instance to create. + This corresponds to the ``instance`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + instance_id (str): + Required. The logical name of the Parallelstore instance + in the user project with the following restrictions: + + - Must contain only lowercase letters, numbers, and + hyphens. + - Must start with a letter. + - Must be between 1-63 characters. + - Must end with a number or a letter. + - Must be unique within the customer project / location + + This corresponds to the ``instance_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.parallelstore_v1beta.types.Instance` + A Parallelstore instance. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, instance, instance_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a parallelstore.CreateInstanceRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, parallelstore.CreateInstanceRequest): + request = parallelstore.CreateInstanceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if instance is not None: + request.instance = instance + if instance_id is not None: + request.instance_id = instance_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_instance] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + parallelstore.Instance, + metadata_type=parallelstore.OperationMetadata, + ) + + # Done; return the response. + return response + + def update_instance( + self, + request: Optional[Union[parallelstore.UpdateInstanceRequest, dict]] = None, + *, + instance: Optional[parallelstore.Instance] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Updates the parameters of a single Instance. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import parallelstore_v1beta + + def sample_update_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreClient() + + # Initialize request argument(s) + instance = parallelstore_v1beta.Instance() + instance.capacity_gib = 1247 + + request = parallelstore_v1beta.UpdateInstanceRequest( + instance=instance, + ) + + # Make the request + operation = client.update_instance(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.parallelstore_v1beta.types.UpdateInstanceRequest, dict]): + The request object. Message for updating a Instance + instance (google.cloud.parallelstore_v1beta.types.Instance): + Required. The instance to update + This corresponds to the ``instance`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. Mask of fields to update .Field mask is used + to specify the fields to be overwritten in the Instance + resource by the update. At least one path must be + supplied in this field. The fields specified in the + update_mask are relative to the resource, not the full + request. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.parallelstore_v1beta.types.Instance` + A Parallelstore instance. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([instance, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a parallelstore.UpdateInstanceRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, parallelstore.UpdateInstanceRequest): + request = parallelstore.UpdateInstanceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if instance is not None: + request.instance = instance + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_instance] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("instance.name", request.instance.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + parallelstore.Instance, + metadata_type=parallelstore.OperationMetadata, + ) + + # Done; return the response. + return response + + def delete_instance( + self, + request: Optional[Union[parallelstore.DeleteInstanceRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Deletes a single Instance. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import parallelstore_v1beta + + def sample_delete_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.DeleteInstanceRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_instance(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.parallelstore_v1beta.types.DeleteInstanceRequest, dict]): + The request object. Message for deleting a Instance + name (str): + Required. Name of the resource + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a parallelstore.DeleteInstanceRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, parallelstore.DeleteInstanceRequest): + request = parallelstore.DeleteInstanceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_instance] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=parallelstore.OperationMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ParallelstoreClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` 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): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # 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): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_operation( + self, + request: Optional[operations_pb2.DeleteOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a long-running operation. + + This method indicates that the client is no longer interested + in the operation result. It does not cancel the operation. + If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # 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): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.delete_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # 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): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.cancel_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.location_pb2.Location: + Location object. + """ + # 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): + request = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_location, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` 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): + request = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_locations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +__all__ = ("ParallelstoreClient",) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/pagers.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/pagers.py new file mode 100644 index 000000000000..9d1abee1429f --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/pagers.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, +) + +from google.cloud.parallelstore_v1beta.types import parallelstore + + +class ListInstancesPager: + """A pager for iterating through ``list_instances`` requests. + + This class thinly wraps an initial + :class:`google.cloud.parallelstore_v1beta.types.ListInstancesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``instances`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListInstances`` requests and continue to iterate + through the ``instances`` field on the + corresponding responses. + + All the usual :class:`google.cloud.parallelstore_v1beta.types.ListInstancesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., parallelstore.ListInstancesResponse], + request: parallelstore.ListInstancesRequest, + response: parallelstore.ListInstancesResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.parallelstore_v1beta.types.ListInstancesRequest): + The initial request object. + response (google.cloud.parallelstore_v1beta.types.ListInstancesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = parallelstore.ListInstancesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[parallelstore.ListInstancesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[parallelstore.Instance]: + for page in self.pages: + yield from page.instances + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListInstancesAsyncPager: + """A pager for iterating through ``list_instances`` requests. + + This class thinly wraps an initial + :class:`google.cloud.parallelstore_v1beta.types.ListInstancesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``instances`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListInstances`` requests and continue to iterate + through the ``instances`` field on the + corresponding responses. + + All the usual :class:`google.cloud.parallelstore_v1beta.types.ListInstancesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., Awaitable[parallelstore.ListInstancesResponse]], + request: parallelstore.ListInstancesRequest, + response: parallelstore.ListInstancesResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.parallelstore_v1beta.types.ListInstancesRequest): + The initial request object. + response (google.cloud.parallelstore_v1beta.types.ListInstancesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = parallelstore.ListInstancesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[parallelstore.ListInstancesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[parallelstore.Instance]: + async def async_generator(): + async for page in self.pages: + for response in page.instances: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/__init__.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/__init__.py new file mode 100644 index 000000000000..cebb16f25a47 --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import ParallelstoreTransport +from .grpc import ParallelstoreGrpcTransport +from .grpc_asyncio import ParallelstoreGrpcAsyncIOTransport +from .rest import ParallelstoreRestInterceptor, ParallelstoreRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ParallelstoreTransport]] +_transport_registry["grpc"] = ParallelstoreGrpcTransport +_transport_registry["grpc_asyncio"] = ParallelstoreGrpcAsyncIOTransport +_transport_registry["rest"] = ParallelstoreRestTransport + +__all__ = ( + "ParallelstoreTransport", + "ParallelstoreGrpcTransport", + "ParallelstoreGrpcAsyncIOTransport", + "ParallelstoreRestTransport", + "ParallelstoreRestInterceptor", +) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/base.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/base.py new file mode 100644 index 000000000000..5c877d2e8d6d --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/base.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.parallelstore_v1beta import gapic_version as package_version +from google.cloud.parallelstore_v1beta.types import parallelstore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +class ParallelstoreTransport(abc.ABC): + """Abstract transport class for Parallelstore.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + DEFAULT_HOST: str = "parallelstore.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'parallelstore.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (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 + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_instances: gapic_v1.method.wrap_method( + self.list_instances, + default_timeout=None, + client_info=client_info, + ), + self.get_instance: gapic_v1.method.wrap_method( + self.get_instance, + default_timeout=None, + client_info=client_info, + ), + self.create_instance: gapic_v1.method.wrap_method( + self.create_instance, + default_timeout=None, + client_info=client_info, + ), + self.update_instance: gapic_v1.method.wrap_method( + self.update_instance, + default_timeout=None, + client_info=client_info, + ), + self.delete_instance: gapic_v1.method.wrap_method( + self.delete_instance, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def list_instances( + self, + ) -> Callable[ + [parallelstore.ListInstancesRequest], + Union[ + parallelstore.ListInstancesResponse, + Awaitable[parallelstore.ListInstancesResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_instance( + self, + ) -> Callable[ + [parallelstore.GetInstanceRequest], + Union[parallelstore.Instance, Awaitable[parallelstore.Instance]], + ]: + raise NotImplementedError() + + @property + def create_instance( + self, + ) -> Callable[ + [parallelstore.CreateInstanceRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def update_instance( + self, + ) -> Callable[ + [parallelstore.UpdateInstanceRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def delete_instance( + self, + ) -> Callable[ + [parallelstore.DeleteInstanceRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None,]: + raise NotImplementedError() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None,]: + raise NotImplementedError() + + @property + def get_location( + self, + ) -> Callable[ + [locations_pb2.GetLocationRequest], + Union[locations_pb2.Location, Awaitable[locations_pb2.Location]], + ]: + raise NotImplementedError() + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], + Union[ + locations_pb2.ListLocationsResponse, + Awaitable[locations_pb2.ListLocationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ParallelstoreTransport",) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/grpc.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/grpc.py new file mode 100644 index 000000000000..d0045c568cfe --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/grpc.py @@ -0,0 +1,515 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from typing import Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers, operations_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import grpc # type: ignore + +from google.cloud.parallelstore_v1beta.types import parallelstore + +from .base import DEFAULT_CLIENT_INFO, ParallelstoreTransport + + +class ParallelstoreGrpcTransport(ParallelstoreTransport): + """gRPC backend transport for Parallelstore. + + Service describing handlers for resources Configures and manages + parallelstore resources. + + Parallelstore service. + + The ``parallelstore.googleapis.com`` service implements the + parallelstore API and defines the following resource model for + managing instances: + + - The service works with a collection of cloud projects, named: + ``/projects/*`` + - Each project has a collection of available locations, named: + ``/locations/*`` + - Each location has a collection of instances named + ``/instances/*``. + - Parallelstore instances are resources of the form: + ``/projects/{project_id}/locations/{location_id}/instances/{instance_id}`` + + Note that location_id must be a Google Cloud ``zone``; for example: + + - ``projects/12345/locations/us-central1-c/instances/my-parallelstore-share`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "parallelstore.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'parallelstore.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the 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 a 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 + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + 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] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + 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: + # 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 + + 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 + + else: + 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 + ) + + # 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, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "parallelstore.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + 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 + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient(self.grpc_channel) + + # Return the client from cache. + return self._operations_client + + @property + def list_instances( + self, + ) -> Callable[ + [parallelstore.ListInstancesRequest], parallelstore.ListInstancesResponse + ]: + r"""Return a callable for the list instances method over gRPC. + + Lists Instances in a given project and location. + + Returns: + Callable[[~.ListInstancesRequest], + ~.ListInstancesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_instances" not in self._stubs: + self._stubs["list_instances"] = self.grpc_channel.unary_unary( + "/google.cloud.parallelstore.v1beta.Parallelstore/ListInstances", + request_serializer=parallelstore.ListInstancesRequest.serialize, + response_deserializer=parallelstore.ListInstancesResponse.deserialize, + ) + return self._stubs["list_instances"] + + @property + def get_instance( + self, + ) -> Callable[[parallelstore.GetInstanceRequest], parallelstore.Instance]: + r"""Return a callable for the get instance method over gRPC. + + Gets details of a single Instance. + + Returns: + Callable[[~.GetInstanceRequest], + ~.Instance]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_instance" not in self._stubs: + self._stubs["get_instance"] = self.grpc_channel.unary_unary( + "/google.cloud.parallelstore.v1beta.Parallelstore/GetInstance", + request_serializer=parallelstore.GetInstanceRequest.serialize, + response_deserializer=parallelstore.Instance.deserialize, + ) + return self._stubs["get_instance"] + + @property + def create_instance( + self, + ) -> Callable[[parallelstore.CreateInstanceRequest], operations_pb2.Operation]: + r"""Return a callable for the create instance method over gRPC. + + Creates a Parallelstore instance in a given project + and location. + + Returns: + Callable[[~.CreateInstanceRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_instance" not in self._stubs: + self._stubs["create_instance"] = self.grpc_channel.unary_unary( + "/google.cloud.parallelstore.v1beta.Parallelstore/CreateInstance", + request_serializer=parallelstore.CreateInstanceRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_instance"] + + @property + def update_instance( + self, + ) -> Callable[[parallelstore.UpdateInstanceRequest], operations_pb2.Operation]: + r"""Return a callable for the update instance method over gRPC. + + Updates the parameters of a single Instance. + + Returns: + Callable[[~.UpdateInstanceRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_instance" not in self._stubs: + self._stubs["update_instance"] = self.grpc_channel.unary_unary( + "/google.cloud.parallelstore.v1beta.Parallelstore/UpdateInstance", + request_serializer=parallelstore.UpdateInstanceRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_instance"] + + @property + def delete_instance( + self, + ) -> Callable[[parallelstore.DeleteInstanceRequest], operations_pb2.Operation]: + r"""Return a callable for the delete instance method over gRPC. + + Deletes a single Instance. + + Returns: + Callable[[~.DeleteInstanceRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_instance" not in self._stubs: + self._stubs["delete_instance"] = self.grpc_channel.unary_unary( + "/google.cloud.parallelstore.v1beta.Parallelstore/DeleteInstance", + request_serializer=parallelstore.DeleteInstanceRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_instance"] + + def close(self): + self.grpc_channel.close() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_locations" not in self._stubs: + self._stubs["list_locations"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_location" not in self._stubs: + self._stubs["get_location"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ParallelstoreGrpcTransport",) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/grpc_asyncio.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/grpc_asyncio.py new file mode 100644 index 000000000000..e2719b762fc5 --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/grpc_asyncio.py @@ -0,0 +1,525 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.parallelstore_v1beta.types import parallelstore + +from .base import DEFAULT_CLIENT_INFO, ParallelstoreTransport +from .grpc import ParallelstoreGrpcTransport + + +class ParallelstoreGrpcAsyncIOTransport(ParallelstoreTransport): + """gRPC AsyncIO backend transport for Parallelstore. + + Service describing handlers for resources Configures and manages + parallelstore resources. + + Parallelstore service. + + The ``parallelstore.googleapis.com`` service implements the + parallelstore API and defines the following resource model for + managing instances: + + - The service works with a collection of cloud projects, named: + ``/projects/*`` + - Each project has a collection of available locations, named: + ``/locations/*`` + - Each location has a collection of instances named + ``/instances/*``. + - Parallelstore instances are resources of the form: + ``/projects/{project_id}/locations/{location_id}/instances/{instance_id}`` + + Note that location_id must be a Google Cloud ``zone``; for example: + + - ``projects/12345/locations/us-central1-c/instances/my-parallelstore-share`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "parallelstore.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + 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 + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "parallelstore.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'parallelstore.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the 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 a 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 + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + 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] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + 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: + # 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 + 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 + + else: + 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 + ) + + # 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, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def list_instances( + self, + ) -> Callable[ + [parallelstore.ListInstancesRequest], + Awaitable[parallelstore.ListInstancesResponse], + ]: + r"""Return a callable for the list instances method over gRPC. + + Lists Instances in a given project and location. + + Returns: + Callable[[~.ListInstancesRequest], + Awaitable[~.ListInstancesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_instances" not in self._stubs: + self._stubs["list_instances"] = self.grpc_channel.unary_unary( + "/google.cloud.parallelstore.v1beta.Parallelstore/ListInstances", + request_serializer=parallelstore.ListInstancesRequest.serialize, + response_deserializer=parallelstore.ListInstancesResponse.deserialize, + ) + return self._stubs["list_instances"] + + @property + def get_instance( + self, + ) -> Callable[ + [parallelstore.GetInstanceRequest], Awaitable[parallelstore.Instance] + ]: + r"""Return a callable for the get instance method over gRPC. + + Gets details of a single Instance. + + Returns: + Callable[[~.GetInstanceRequest], + Awaitable[~.Instance]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_instance" not in self._stubs: + self._stubs["get_instance"] = self.grpc_channel.unary_unary( + "/google.cloud.parallelstore.v1beta.Parallelstore/GetInstance", + request_serializer=parallelstore.GetInstanceRequest.serialize, + response_deserializer=parallelstore.Instance.deserialize, + ) + return self._stubs["get_instance"] + + @property + def create_instance( + self, + ) -> Callable[ + [parallelstore.CreateInstanceRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the create instance method over gRPC. + + Creates a Parallelstore instance in a given project + and location. + + Returns: + Callable[[~.CreateInstanceRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_instance" not in self._stubs: + self._stubs["create_instance"] = self.grpc_channel.unary_unary( + "/google.cloud.parallelstore.v1beta.Parallelstore/CreateInstance", + request_serializer=parallelstore.CreateInstanceRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_instance"] + + @property + def update_instance( + self, + ) -> Callable[ + [parallelstore.UpdateInstanceRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the update instance method over gRPC. + + Updates the parameters of a single Instance. + + Returns: + Callable[[~.UpdateInstanceRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_instance" not in self._stubs: + self._stubs["update_instance"] = self.grpc_channel.unary_unary( + "/google.cloud.parallelstore.v1beta.Parallelstore/UpdateInstance", + request_serializer=parallelstore.UpdateInstanceRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_instance"] + + @property + def delete_instance( + self, + ) -> Callable[ + [parallelstore.DeleteInstanceRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the delete instance method over gRPC. + + Deletes a single Instance. + + Returns: + Callable[[~.DeleteInstanceRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_instance" not in self._stubs: + self._stubs["delete_instance"] = self.grpc_channel.unary_unary( + "/google.cloud.parallelstore.v1beta.Parallelstore/DeleteInstance", + request_serializer=parallelstore.DeleteInstanceRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_instance"] + + def close(self): + return self.grpc_channel.close() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_locations" not in self._stubs: + self._stubs["list_locations"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_location" not in self._stubs: + self._stubs["get_location"] = self.grpc_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + + +__all__ = ("ParallelstoreGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/rest.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/rest.py new file mode 100644 index 000000000000..1fdde7d6445d --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/services/parallelstore/transports/rest.py @@ -0,0 +1,1432 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# + +import dataclasses +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import ( + gapic_v1, + operations_v1, + path_template, + rest_helpers, + rest_streaming, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.protobuf import json_format +import grpc # type: ignore +from requests import __version__ as requests_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + + +from google.longrunning import operations_pb2 # type: ignore + +from google.cloud.parallelstore_v1beta.types import parallelstore + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .base import ParallelstoreTransport + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class ParallelstoreRestInterceptor: + """Interceptor for Parallelstore. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ParallelstoreRestTransport. + + .. code-block:: python + class MyCustomParallelstoreInterceptor(ParallelstoreRestInterceptor): + def pre_create_instance(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_instance(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_instance(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_delete_instance(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_instance(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_instance(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_instances(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_instances(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_instance(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_instance(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ParallelstoreRestTransport(interceptor=MyCustomParallelstoreInterceptor()) + client = ParallelstoreClient(transport=transport) + + + """ + + def pre_create_instance( + self, + request: parallelstore.CreateInstanceRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[parallelstore.CreateInstanceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_instance + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_create_instance( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_instance + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + def pre_delete_instance( + self, + request: parallelstore.DeleteInstanceRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[parallelstore.DeleteInstanceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_instance + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_delete_instance( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for delete_instance + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + def pre_get_instance( + self, + request: parallelstore.GetInstanceRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[parallelstore.GetInstanceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_instance + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_get_instance( + self, response: parallelstore.Instance + ) -> parallelstore.Instance: + """Post-rpc interceptor for get_instance + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + def pre_list_instances( + self, + request: parallelstore.ListInstancesRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[parallelstore.ListInstancesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_instances + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_list_instances( + self, response: parallelstore.ListInstancesResponse + ) -> parallelstore.ListInstancesResponse: + """Post-rpc interceptor for list_instances + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + def pre_update_instance( + self, + request: parallelstore.UpdateInstanceRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[parallelstore.UpdateInstanceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_instance + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_update_instance( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for update_instance + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + def pre_get_location( + self, + request: locations_pb2.GetLocationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[locations_pb2.GetLocationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_location + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_get_location( + self, response: locations_pb2.Location + ) -> locations_pb2.Location: + """Post-rpc interceptor for get_location + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + def pre_list_locations( + self, + request: locations_pb2.ListLocationsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[locations_pb2.ListLocationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_locations + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_list_locations( + self, response: locations_pb2.ListLocationsResponse + ) -> locations_pb2.ListLocationsResponse: + """Post-rpc interceptor for list_locations + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + def pre_cancel_operation( + self, + request: operations_pb2.CancelOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.CancelOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_cancel_operation(self, response: None) -> None: + """Post-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + def pre_delete_operation( + self, + request: operations_pb2.DeleteOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.DeleteOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_delete_operation(self, response: None) -> None: + """Post-rpc interceptor for delete_operation + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the Parallelstore server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the Parallelstore server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ParallelstoreRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ParallelstoreRestInterceptor + + +class ParallelstoreRestTransport(ParallelstoreTransport): + """REST backend transport for Parallelstore. + + Service describing handlers for resources Configures and manages + parallelstore resources. + + Parallelstore service. + + The ``parallelstore.googleapis.com`` service implements the + parallelstore API and defines the following resource model for + managing instances: + + - The service works with a collection of cloud projects, named: + ``/projects/*`` + - Each project has a collection of available locations, named: + ``/locations/*`` + - Each location has a collection of instances named + ``/instances/*``. + - Parallelstore instances are resources of the form: + ``/projects/{project_id}/locations/{location_id}/instances/{instance_id}`` + + Note that location_id must be a Google Cloud ``zone``; for example: + + - ``projects/12345/locations/us-central1-c/instances/my-parallelstore-share`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__( + self, + *, + host: str = "parallelstore.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[ParallelstoreRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'parallelstore.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` 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 are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ParallelstoreRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.CancelOperation": [ + { + "method": "post", + "uri": "/v1beta/{name=projects/*/locations/*/operations/*}:cancel", + "body": "*", + }, + ], + "google.longrunning.Operations.DeleteOperation": [ + { + "method": "delete", + "uri": "/v1beta/{name=projects/*/locations/*/operations/*}", + }, + ], + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/operations/*}", + }, + ], + "google.longrunning.Operations.ListOperations": [ + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*}/operations", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1beta", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _CreateInstance(ParallelstoreRestStub): + def __hash__(self): + return hash("CreateInstance") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "instanceId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: parallelstore.CreateInstanceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the create instance method over HTTP. + + Args: + request (~.parallelstore.CreateInstanceRequest): + The request object. Request for + [CreateInstance][google.cloud.parallelstore.v1beta.Parallelstore.CreateInstance] + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta/{parent=projects/*/locations/*}/instances", + "body": "instance", + }, + ] + request, metadata = self._interceptor.pre_create_instance(request, metadata) + pb_request = parallelstore.CreateInstanceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_instance(resp) + return resp + + class _DeleteInstance(ParallelstoreRestStub): + def __hash__(self): + return hash("DeleteInstance") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: parallelstore.DeleteInstanceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete instance method over HTTP. + + Args: + request (~.parallelstore.DeleteInstanceRequest): + The request object. Message for deleting a Instance + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1beta/{name=projects/*/locations/*/instances/*}", + }, + ] + request, metadata = self._interceptor.pre_delete_instance(request, metadata) + pb_request = parallelstore.DeleteInstanceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_delete_instance(resp) + return resp + + class _GetInstance(ParallelstoreRestStub): + def __hash__(self): + return hash("GetInstance") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: parallelstore.GetInstanceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> parallelstore.Instance: + r"""Call the get instance method over HTTP. + + Args: + request (~.parallelstore.GetInstanceRequest): + The request object. Request to get an instance's details. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.parallelstore.Instance: + A Parallelstore instance. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/instances/*}", + }, + ] + request, metadata = self._interceptor.pre_get_instance(request, metadata) + pb_request = parallelstore.GetInstanceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = parallelstore.Instance() + pb_resp = parallelstore.Instance.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_instance(resp) + return resp + + class _ListInstances(ParallelstoreRestStub): + def __hash__(self): + return hash("ListInstances") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: parallelstore.ListInstancesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> parallelstore.ListInstancesResponse: + r"""Call the list instances method over HTTP. + + Args: + request (~.parallelstore.ListInstancesRequest): + The request object. Message for requesting list of + Instances + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.parallelstore.ListInstancesResponse: + Message for response to listing + Instances + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1beta/{parent=projects/*/locations/*}/instances", + }, + ] + request, metadata = self._interceptor.pre_list_instances(request, metadata) + pb_request = parallelstore.ListInstancesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = parallelstore.ListInstancesResponse() + pb_resp = parallelstore.ListInstancesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_instances(resp) + return resp + + class _UpdateInstance(ParallelstoreRestStub): + def __hash__(self): + return hash("UpdateInstance") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: parallelstore.UpdateInstanceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the update instance method over HTTP. + + Args: + request (~.parallelstore.UpdateInstanceRequest): + The request object. Message for updating a Instance + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1beta/{instance.name=projects/*/locations/*/instances/*}", + "body": "instance", + }, + ] + request, metadata = self._interceptor.pre_update_instance(request, metadata) + pb_request = parallelstore.UpdateInstanceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_instance(resp) + return resp + + @property + def create_instance( + self, + ) -> Callable[[parallelstore.CreateInstanceRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateInstance(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_instance( + self, + ) -> Callable[[parallelstore.DeleteInstanceRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteInstance(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_instance( + self, + ) -> Callable[[parallelstore.GetInstanceRequest], parallelstore.Instance]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetInstance(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_instances( + self, + ) -> Callable[ + [parallelstore.ListInstancesRequest], parallelstore.ListInstancesResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListInstances(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_instance( + self, + ) -> Callable[[parallelstore.UpdateInstanceRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateInstance(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_location(self): + return self._GetLocation(self._session, self._host, self._interceptor) # type: ignore + + class _GetLocation(ParallelstoreRestStub): + def __call__( + self, + request: locations_pb2.GetLocationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.Location: + r"""Call the get location method over HTTP. + + Args: + request (locations_pb2.GetLocationRequest): + The request object for GetLocation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + locations_pb2.Location: Response from GetLocation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*}", + }, + ] + + request, metadata = self._interceptor.pre_get_location(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = locations_pb2.Location() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_location(resp) + return resp + + @property + def list_locations(self): + return self._ListLocations(self._session, self._host, self._interceptor) # type: ignore + + class _ListLocations(ParallelstoreRestStub): + def __call__( + self, + request: locations_pb2.ListLocationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Call the list locations method over HTTP. + + Args: + request (locations_pb2.ListLocationsRequest): + The request object for ListLocations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + locations_pb2.ListLocationsResponse: Response from ListLocations method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1beta/{name=projects/*}/locations", + }, + ] + + request, metadata = self._interceptor.pre_list_locations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = locations_pb2.ListLocationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_locations(resp) + return resp + + @property + def cancel_operation(self): + return self._CancelOperation(self._session, self._host, self._interceptor) # type: ignore + + class _CancelOperation(ParallelstoreRestStub): + def __call__( + self, + request: operations_pb2.CancelOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Call the cancel operation method over HTTP. + + Args: + request (operations_pb2.CancelOperationRequest): + The request object for CancelOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta/{name=projects/*/locations/*/operations/*}:cancel", + "body": "*", + }, + ] + + request, metadata = self._interceptor.pre_cancel_operation( + request, metadata + ) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + body = json.dumps(transcoded_request["body"]) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_cancel_operation(None) + + @property + def delete_operation(self): + return self._DeleteOperation(self._session, self._host, self._interceptor) # type: ignore + + class _DeleteOperation(ParallelstoreRestStub): + def __call__( + self, + request: operations_pb2.DeleteOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Call the delete operation method over HTTP. + + Args: + request (operations_pb2.DeleteOperationRequest): + The request object for DeleteOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1beta/{name=projects/*/locations/*/operations/*}", + }, + ] + + request, metadata = self._interceptor.pre_delete_operation( + request, metadata + ) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_delete_operation(None) + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ParallelstoreRestStub): + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*/operations/*}", + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ParallelstoreRestStub): + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1beta/{name=projects/*/locations/*}/operations", + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("ParallelstoreRestTransport",) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/types/__init__.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/types/__init__.py new file mode 100644 index 000000000000..be7f46a5e0e5 --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/types/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from .parallelstore import ( + CreateInstanceRequest, + DeleteInstanceRequest, + GetInstanceRequest, + Instance, + ListInstancesRequest, + ListInstancesResponse, + OperationMetadata, + UpdateInstanceRequest, +) + +__all__ = ( + "CreateInstanceRequest", + "DeleteInstanceRequest", + "GetInstanceRequest", + "Instance", + "ListInstancesRequest", + "ListInstancesResponse", + "OperationMetadata", + "UpdateInstanceRequest", +) diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/types/parallelstore.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/types/parallelstore.py new file mode 100644 index 000000000000..6f18e9511bae --- /dev/null +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/types/parallelstore.py @@ -0,0 +1,486 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.parallelstore.v1beta", + manifest={ + "Instance", + "ListInstancesRequest", + "ListInstancesResponse", + "GetInstanceRequest", + "CreateInstanceRequest", + "UpdateInstanceRequest", + "DeleteInstanceRequest", + "OperationMetadata", + }, +) + + +class Instance(proto.Message): + r"""A Parallelstore instance. + + Attributes: + name (str): + Identifier. The resource name of the instance, in the format + ``projects/{project}/locations/{location}/instances/{instance_id}`` + description (str): + Optional. The description of the instance. + 2048 characters or less. + state (google.cloud.parallelstore_v1beta.types.Instance.State): + Output only. The instance state. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time when the instance was + created. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time when the instance was + updated. + labels (MutableMapping[str, str]): + Optional. Cloud Labels are a flexible and lightweight + mechanism for organizing cloud resources into groups that + reflect a customer's organizational needs and deployment + strategies. Cloud Labels can be used to filter collections + of resources. They can be used to control how resource + metrics are aggregated. And they can be used as arguments to + policy management rules (e.g. route, firewall, load + balancing, etc.). + + - Label keys must be between 1 and 63 characters long and + must conform to the following regular expression: + ``[a-z][a-z0-9_-]{0,62}``. + - Label values must be between 0 and 63 characters long and + must conform to the regular expression + ``[a-z0-9_-]{0,63}``. + - No more than 64 labels can be associated with a given + resource. + + See https://goo.gl/xmQnxf for more information on and + examples of labels. + + If you plan to use labels in your own code, please note that + additional characters may be allowed in the future. + Therefore, you are advised to use an internal label + representation, such as JSON, which doesn't rely upon + specific characters being disallowed. For example, + representing labels as the string: name + "*" + value would + prove problematic if we were to allow "*" in a future + release. + capacity_gib (int): + Required. Immutable. Storage capacity of + Parallelstore instance in Gibibytes (GiB). + daos_version (str): + Output only. The version of DAOS software + running in the instance + access_points (MutableSequence[str]): + Output only. List of access_points. Contains a list of IPv4 + addresses used for client side configuration. + network (str): + Optional. Immutable. The name of the Google Compute Engine + `VPC network `__ to + which the instance is connected. + reserved_ip_range (str): + Optional. Immutable. Contains the id of + allocated IP address range associated with the + private service access connection for example, + "test-default" associated with IP range + 10.0.0.0/29. If no range id is provided all + ranges will be considered. + """ + + class State(proto.Enum): + r"""Represents the different states of a Parallelstore instance. + + Values: + STATE_UNSPECIFIED (0): + Not set. + CREATING (1): + The instance is being created. + ACTIVE (2): + The instance is available for use. + DELETING (3): + The instance is being deleted. + FAILED (4): + The instance is not usable. + """ + STATE_UNSPECIFIED = 0 + CREATING = 1 + ACTIVE = 2 + DELETING = 3 + FAILED = 4 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + state: State = proto.Field( + proto.ENUM, + number=3, + enum=State, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=6, + ) + capacity_gib: int = proto.Field( + proto.INT64, + number=8, + ) + daos_version: str = proto.Field( + proto.STRING, + number=9, + ) + access_points: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=10, + ) + network: str = proto.Field( + proto.STRING, + number=11, + ) + reserved_ip_range: str = proto.Field( + proto.STRING, + number=12, + ) + + +class ListInstancesRequest(proto.Message): + r"""Message for requesting list of Instances + + Attributes: + parent (str): + Required. The project and location for which to retrieve + instance information, in the format + ``projects/{project_id}/locations/{location}``. For + Parallelstore locations map to Google Cloud zones, for + example **us-central1-a**. To retrieve instance information + for all locations, use "-" for the ``{location}`` value. + page_size (int): + Optional. Requested page size. Server may + return fewer items than requested. If + unspecified, server will pick an appropriate + default. + page_token (str): + Optional. A token identifying a page of + results the server should return. + filter (str): + Optional. Filtering results + order_by (str): + Optional. Hint for how to order the results + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + + +class ListInstancesResponse(proto.Message): + r"""Message for response to listing Instances + + Attributes: + instances (MutableSequence[google.cloud.parallelstore_v1beta.types.Instance]): + The list of Parallelstore Instances + next_page_token (str): + A token identifying a page of results the + server should return. + unreachable (MutableSequence[str]): + Locations that could not be reached. + """ + + @property + def raw_page(self): + return self + + instances: MutableSequence["Instance"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Instance", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class GetInstanceRequest(proto.Message): + r"""Request to get an instance's details. + + Attributes: + name (str): + Required. The instance resource name, in the format + ``projects/{project_id}/locations/{location}/instances/{instance_id}``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateInstanceRequest(proto.Message): + r"""Request for + [CreateInstance][google.cloud.parallelstore.v1beta.Parallelstore.CreateInstance] + + Attributes: + parent (str): + Required. The instance's project and location, in the format + ``projects/{project}/locations/{location}``. Locations map + to Google Cloud zones, for example **us-west1-b**. + instance_id (str): + Required. The logical name of the Parallelstore instance in + the user project with the following restrictions: + + - Must contain only lowercase letters, numbers, and + hyphens. + - Must start with a letter. + - Must be between 1-63 characters. + - Must end with a number or a letter. + - Must be unique within the customer project / location + instance (google.cloud.parallelstore_v1beta.types.Instance): + Required. The instance to create. + request_id (str): + Optional. An optional request ID to identify + requests. Specify a unique request ID so that if + you must retry your request, the server will + know to ignore the request if it has already + been completed. The server will guarantee that + for at least 60 minutes since the first request. + + For example, consider a situation where you make + an initial request and t he request times out. + If you make the request again with the same + request ID, the server can check if original + operation with the same request ID was received, + and if so, will ignore the second request. This + prevents clients from accidentally creating + duplicate commitments. + + The request ID must be a valid UUID with the + exception that zero UUID is not supported + (00000000-0000-0000-0000-000000000000). + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + instance_id: str = proto.Field( + proto.STRING, + number=2, + ) + instance: "Instance" = proto.Field( + proto.MESSAGE, + number=3, + message="Instance", + ) + request_id: str = proto.Field( + proto.STRING, + number=4, + ) + + +class UpdateInstanceRequest(proto.Message): + r"""Message for updating a Instance + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. Mask of fields to update .Field mask is used to + specify the fields to be overwritten in the Instance + resource by the update. At least one path must be supplied + in this field. The fields specified in the update_mask are + relative to the resource, not the full request. + instance (google.cloud.parallelstore_v1beta.types.Instance): + Required. The instance to update + request_id (str): + Optional. An optional request ID to identify + requests. Specify a unique request ID so that if + you must retry your request, the server will + know to ignore the request if it has already + been completed. The server will guarantee that + for at least 60 minutes since the first request. + + For example, consider a situation where you make + an initial request and t he request times out. + If you make the request again with the same + request ID, the server can check if original + operation with the same request ID was received, + and if so, will ignore the second request. This + prevents clients from accidentally creating + duplicate commitments. + + The request ID must be a valid UUID with the + exception that zero UUID is not supported + (00000000-0000-0000-0000-000000000000). + """ + + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=1, + message=field_mask_pb2.FieldMask, + ) + instance: "Instance" = proto.Field( + proto.MESSAGE, + number=2, + message="Instance", + ) + request_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class DeleteInstanceRequest(proto.Message): + r"""Message for deleting a Instance + + Attributes: + name (str): + Required. Name of the resource + request_id (str): + Optional. An optional request ID to identify + requests. Specify a unique request ID so that if + you must retry your request, the server will + know to ignore the request if it has already + been completed. The server will guarantee that + for at least 60 minutes after the first request. + + For example, consider a situation where you make + an initial request and t he request times out. + If you make the request again with the same + request ID, the server can check if original + operation with the same request ID was received, + and if so, will ignore the second request. This + prevents clients from accidentally creating + duplicate commitments. + + The request ID must be a valid UUID with the + exception that zero UUID is not supported + (00000000-0000-0000-0000-000000000000). + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + request_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class OperationMetadata(proto.Message): + r"""Represents the metadata of the long-running operation. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time the operation was + created. + end_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time the operation finished + running. + target (str): + Output only. Server-defined resource path for + the target of the operation. + verb (str): + Output only. Name of the verb executed by the + operation. + status_message (str): + Output only. Human-readable status of the + operation, if any. + requested_cancellation (bool): + Output only. Identifies whether the user has requested + cancellation of the operation. Operations that have been + cancelled successfully have [Operation.error][] value with a + [google.rpc.Status.code][google.rpc.Status.code] of 1, + corresponding to ``Code.CANCELLED``. + api_version (str): + Output only. API version used to start the + operation. + """ + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + target: str = proto.Field( + proto.STRING, + number=3, + ) + verb: str = proto.Field( + proto.STRING, + number=4, + ) + status_message: str = proto.Field( + proto.STRING, + number=5, + ) + requested_cancellation: bool = proto.Field( + proto.BOOL, + number=6, + ) + api_version: str = proto.Field( + proto.STRING, + number=7, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-parallelstore/mypy.ini b/packages/google-cloud-parallelstore/mypy.ini new file mode 100644 index 000000000000..574c5aed394b --- /dev/null +++ b/packages/google-cloud-parallelstore/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/packages/google-cloud-parallelstore/noxfile.py b/packages/google-cloud-parallelstore/noxfile.py new file mode 100644 index 000000000000..1e6cd48d0529 --- /dev/null +++ b/packages/google-cloud-parallelstore/noxfile.py @@ -0,0 +1,428 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2023 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. + +# Generated by synthtool. DO NOT EDIT! + +from __future__ import absolute_import + +import os +import pathlib +import re +import shutil +from typing import Dict, List +import warnings + +import nox + +BLACK_VERSION = "black[jupyter]==23.7.0" +ISORT_VERSION = "isort==5.11.0" + +LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] + + +DEFAULT_PYTHON_VERSION = "3.10" + +UNIT_TEST_PYTHON_VERSIONS: List[str] = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] +UNIT_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "asyncmock", + "pytest", + "pytest-cov", + "pytest-asyncio", +] +UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_DEPENDENCIES: List[str] = [] +UNIT_TEST_EXTRAS: List[str] = [] +UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12"] +SYSTEM_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "pytest", + "google-cloud-testutils", +] +SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_EXTRAS: List[str] = [] +SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +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): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", BLACK_VERSION) + session.run( + "black", + "--check", + *LINT_PATHS, + ) + + session.run("flake8", "google", "tests") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + session.run( + "black", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run( + "isort", + "--fss", + *LINT_PATHS, + ) + session.run( + "black", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") + + +def install_unittest_dependencies(session, *constraints): + standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES + session.install(*standard_deps, *constraints) + + if UNIT_TEST_EXTERNAL_DEPENDENCIES: + warnings.warn( + "'unit_test_external_dependencies' is deprecated. Instead, please " + "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", + DeprecationWarning, + ) + session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_LOCAL_DEPENDENCIES: + session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_EXTRAS_BY_PYTHON: + extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif UNIT_TEST_EXTRAS: + extras = UNIT_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +def default(session): + # Install all test dependencies, then install this package in-place. + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + install_unittest_dependencies(session, "-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", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + os.path.join("tests", "unit"), + *session.posargs, + ) + + +@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) +def unit(session): + """Run the unit test suite.""" + default(session) + + +def install_systemtest_dependencies(session, *constraints): + # Use pre-release gRPC for system tests. + # Exclude version 1.52.0rc1 which has a known issue. + # See https://github.com/grpc/grpc/issues/32163 + session.install("--pre", "grpcio!=1.52.0rc1") + + session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: + session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_LOCAL_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTRAS_BY_PYTHON: + extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif SYSTEM_TEST_EXTRAS: + extras = SYSTEM_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@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") + + # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. + if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": + session.skip("RUN_SYSTEM_TESTS is set to false, skipping") + # 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) + # Sanity check: only run tests if found. + if not system_test_exists and not system_test_folder_exists: + session.skip("System tests were not found") + + install_systemtest_dependencies(session, "-c", constraints_path) + + # Run py.test against the system tests. + if system_test_exists: + 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", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def cover(session): + """Run the final coverage report. + + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=100") + + session.run("coverage", "erase") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "sphinx==4.5.0", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "gcp-sphinx-docfx-yaml", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python="3.12") +def prerelease_deps(session): + """Run all tests with prerelease versions of dependencies installed.""" + + # Install all dependencies + session.install("-e", ".[all, tests, tracing]") + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + system_deps_all = ( + SYSTEM_TEST_STANDARD_DEPENDENCIES + + SYSTEM_TEST_EXTERNAL_DEPENDENCIES + + SYSTEM_TEST_EXTRAS + ) + session.install(*system_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY + / "testing" + / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + session.install(*constraints_deps) + + prerel_deps = [ + "protobuf", + # dependency of grpc + "six", + "googleapis-common-protos", + # Exclude version 1.52.0rc1 which has a known issue. See https://github.com/grpc/grpc/issues/32163 + "grpcio!=1.52.0rc1", + "grpcio-status", + "google-api-core", + "google-auth", + "proto-plus", + "google-cloud-testutils", + # dependencies of google-cloud-testutils" + "click", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--upgrade", dep) + + # Remaining dependencies + other_deps = [ + "requests", + ] + session.install(*other_deps) + + # Print out prerelease package versions + session.run( + "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" + ) + session.run("python", "-c", "import grpc; print(grpc.__version__)") + session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + + session.run("py.test", "tests/unit") diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_create_instance_async.py b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_create_instance_async.py new file mode 100644 index 000000000000..000acd3e074b --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_create_instance_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateInstance +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-parallelstore + + +# [START parallelstore_v1beta_generated_Parallelstore_CreateInstance_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import parallelstore_v1beta + + +async def sample_create_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreAsyncClient() + + # Initialize request argument(s) + instance = parallelstore_v1beta.Instance() + instance.capacity_gib = 1247 + + request = parallelstore_v1beta.CreateInstanceRequest( + parent="parent_value", + instance_id="instance_id_value", + instance=instance, + ) + + # Make the request + operation = client.create_instance(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END parallelstore_v1beta_generated_Parallelstore_CreateInstance_async] diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_create_instance_sync.py b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_create_instance_sync.py new file mode 100644 index 000000000000..73984b5ac1a5 --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_create_instance_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateInstance +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-parallelstore + + +# [START parallelstore_v1beta_generated_Parallelstore_CreateInstance_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import parallelstore_v1beta + + +def sample_create_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreClient() + + # Initialize request argument(s) + instance = parallelstore_v1beta.Instance() + instance.capacity_gib = 1247 + + request = parallelstore_v1beta.CreateInstanceRequest( + parent="parent_value", + instance_id="instance_id_value", + instance=instance, + ) + + # Make the request + operation = client.create_instance(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END parallelstore_v1beta_generated_Parallelstore_CreateInstance_sync] diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_delete_instance_async.py b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_delete_instance_async.py new file mode 100644 index 000000000000..70fae7244908 --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_delete_instance_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteInstance +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-parallelstore + + +# [START parallelstore_v1beta_generated_Parallelstore_DeleteInstance_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import parallelstore_v1beta + + +async def sample_delete_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreAsyncClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.DeleteInstanceRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_instance(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END parallelstore_v1beta_generated_Parallelstore_DeleteInstance_async] diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_delete_instance_sync.py b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_delete_instance_sync.py new file mode 100644 index 000000000000..4777b3954842 --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_delete_instance_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteInstance +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-parallelstore + + +# [START parallelstore_v1beta_generated_Parallelstore_DeleteInstance_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import parallelstore_v1beta + + +def sample_delete_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.DeleteInstanceRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_instance(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END parallelstore_v1beta_generated_Parallelstore_DeleteInstance_sync] diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_get_instance_async.py b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_get_instance_async.py new file mode 100644 index 000000000000..5901a2b1f803 --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_get_instance_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetInstance +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-parallelstore + + +# [START parallelstore_v1beta_generated_Parallelstore_GetInstance_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import parallelstore_v1beta + + +async def sample_get_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreAsyncClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.GetInstanceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_instance(request=request) + + # Handle the response + print(response) + +# [END parallelstore_v1beta_generated_Parallelstore_GetInstance_async] diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_get_instance_sync.py b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_get_instance_sync.py new file mode 100644 index 000000000000..9881af800972 --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_get_instance_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetInstance +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-parallelstore + + +# [START parallelstore_v1beta_generated_Parallelstore_GetInstance_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import parallelstore_v1beta + + +def sample_get_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.GetInstanceRequest( + name="name_value", + ) + + # Make the request + response = client.get_instance(request=request) + + # Handle the response + print(response) + +# [END parallelstore_v1beta_generated_Parallelstore_GetInstance_sync] diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_list_instances_async.py b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_list_instances_async.py new file mode 100644 index 000000000000..3397c9fbd705 --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_list_instances_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListInstances +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-parallelstore + + +# [START parallelstore_v1beta_generated_Parallelstore_ListInstances_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import parallelstore_v1beta + + +async def sample_list_instances(): + # Create a client + client = parallelstore_v1beta.ParallelstoreAsyncClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.ListInstancesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_instances(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END parallelstore_v1beta_generated_Parallelstore_ListInstances_async] diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_list_instances_sync.py b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_list_instances_sync.py new file mode 100644 index 000000000000..6b2436756a0e --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_list_instances_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListInstances +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-parallelstore + + +# [START parallelstore_v1beta_generated_Parallelstore_ListInstances_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import parallelstore_v1beta + + +def sample_list_instances(): + # Create a client + client = parallelstore_v1beta.ParallelstoreClient() + + # Initialize request argument(s) + request = parallelstore_v1beta.ListInstancesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_instances(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END parallelstore_v1beta_generated_Parallelstore_ListInstances_sync] diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_update_instance_async.py b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_update_instance_async.py new file mode 100644 index 000000000000..1a50057e79a1 --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_update_instance_async.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateInstance +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-parallelstore + + +# [START parallelstore_v1beta_generated_Parallelstore_UpdateInstance_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import parallelstore_v1beta + + +async def sample_update_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreAsyncClient() + + # Initialize request argument(s) + instance = parallelstore_v1beta.Instance() + instance.capacity_gib = 1247 + + request = parallelstore_v1beta.UpdateInstanceRequest( + instance=instance, + ) + + # Make the request + operation = client.update_instance(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END parallelstore_v1beta_generated_Parallelstore_UpdateInstance_async] diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_update_instance_sync.py b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_update_instance_sync.py new file mode 100644 index 000000000000..8df289175420 --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/parallelstore_v1beta_generated_parallelstore_update_instance_sync.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateInstance +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-parallelstore + + +# [START parallelstore_v1beta_generated_Parallelstore_UpdateInstance_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import parallelstore_v1beta + + +def sample_update_instance(): + # Create a client + client = parallelstore_v1beta.ParallelstoreClient() + + # Initialize request argument(s) + instance = parallelstore_v1beta.Instance() + instance.capacity_gib = 1247 + + request = parallelstore_v1beta.UpdateInstanceRequest( + instance=instance, + ) + + # Make the request + operation = client.update_instance(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END parallelstore_v1beta_generated_Parallelstore_UpdateInstance_sync] diff --git a/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1beta.json b/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1beta.json new file mode 100644 index 000000000000..29740f11cc45 --- /dev/null +++ b/packages/google-cloud-parallelstore/samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1beta.json @@ -0,0 +1,844 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.parallelstore.v1beta", + "version": "v1beta" + } + ], + "language": "PYTHON", + "name": "google-cloud-parallelstore", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreAsyncClient", + "shortName": "ParallelstoreAsyncClient" + }, + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreAsyncClient.create_instance", + "method": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore.CreateInstance", + "service": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore", + "shortName": "Parallelstore" + }, + "shortName": "CreateInstance" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.parallelstore_v1beta.types.CreateInstanceRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "instance", + "type": "google.cloud.parallelstore_v1beta.types.Instance" + }, + { + "name": "instance_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "create_instance" + }, + "description": "Sample for CreateInstance", + "file": "parallelstore_v1beta_generated_parallelstore_create_instance_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "parallelstore_v1beta_generated_Parallelstore_CreateInstance_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "parallelstore_v1beta_generated_parallelstore_create_instance_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreClient", + "shortName": "ParallelstoreClient" + }, + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreClient.create_instance", + "method": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore.CreateInstance", + "service": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore", + "shortName": "Parallelstore" + }, + "shortName": "CreateInstance" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.parallelstore_v1beta.types.CreateInstanceRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "instance", + "type": "google.cloud.parallelstore_v1beta.types.Instance" + }, + { + "name": "instance_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "create_instance" + }, + "description": "Sample for CreateInstance", + "file": "parallelstore_v1beta_generated_parallelstore_create_instance_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "parallelstore_v1beta_generated_Parallelstore_CreateInstance_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "parallelstore_v1beta_generated_parallelstore_create_instance_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreAsyncClient", + "shortName": "ParallelstoreAsyncClient" + }, + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreAsyncClient.delete_instance", + "method": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore.DeleteInstance", + "service": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore", + "shortName": "Parallelstore" + }, + "shortName": "DeleteInstance" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.parallelstore_v1beta.types.DeleteInstanceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_instance" + }, + "description": "Sample for DeleteInstance", + "file": "parallelstore_v1beta_generated_parallelstore_delete_instance_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "parallelstore_v1beta_generated_Parallelstore_DeleteInstance_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "parallelstore_v1beta_generated_parallelstore_delete_instance_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreClient", + "shortName": "ParallelstoreClient" + }, + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreClient.delete_instance", + "method": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore.DeleteInstance", + "service": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore", + "shortName": "Parallelstore" + }, + "shortName": "DeleteInstance" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.parallelstore_v1beta.types.DeleteInstanceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_instance" + }, + "description": "Sample for DeleteInstance", + "file": "parallelstore_v1beta_generated_parallelstore_delete_instance_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "parallelstore_v1beta_generated_Parallelstore_DeleteInstance_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "parallelstore_v1beta_generated_parallelstore_delete_instance_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreAsyncClient", + "shortName": "ParallelstoreAsyncClient" + }, + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreAsyncClient.get_instance", + "method": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore.GetInstance", + "service": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore", + "shortName": "Parallelstore" + }, + "shortName": "GetInstance" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.parallelstore_v1beta.types.GetInstanceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.parallelstore_v1beta.types.Instance", + "shortName": "get_instance" + }, + "description": "Sample for GetInstance", + "file": "parallelstore_v1beta_generated_parallelstore_get_instance_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "parallelstore_v1beta_generated_Parallelstore_GetInstance_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "parallelstore_v1beta_generated_parallelstore_get_instance_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreClient", + "shortName": "ParallelstoreClient" + }, + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreClient.get_instance", + "method": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore.GetInstance", + "service": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore", + "shortName": "Parallelstore" + }, + "shortName": "GetInstance" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.parallelstore_v1beta.types.GetInstanceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.parallelstore_v1beta.types.Instance", + "shortName": "get_instance" + }, + "description": "Sample for GetInstance", + "file": "parallelstore_v1beta_generated_parallelstore_get_instance_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "parallelstore_v1beta_generated_Parallelstore_GetInstance_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "parallelstore_v1beta_generated_parallelstore_get_instance_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreAsyncClient", + "shortName": "ParallelstoreAsyncClient" + }, + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreAsyncClient.list_instances", + "method": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore.ListInstances", + "service": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore", + "shortName": "Parallelstore" + }, + "shortName": "ListInstances" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.parallelstore_v1beta.types.ListInstancesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.parallelstore_v1beta.services.parallelstore.pagers.ListInstancesAsyncPager", + "shortName": "list_instances" + }, + "description": "Sample for ListInstances", + "file": "parallelstore_v1beta_generated_parallelstore_list_instances_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "parallelstore_v1beta_generated_Parallelstore_ListInstances_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "parallelstore_v1beta_generated_parallelstore_list_instances_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreClient", + "shortName": "ParallelstoreClient" + }, + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreClient.list_instances", + "method": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore.ListInstances", + "service": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore", + "shortName": "Parallelstore" + }, + "shortName": "ListInstances" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.parallelstore_v1beta.types.ListInstancesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.parallelstore_v1beta.services.parallelstore.pagers.ListInstancesPager", + "shortName": "list_instances" + }, + "description": "Sample for ListInstances", + "file": "parallelstore_v1beta_generated_parallelstore_list_instances_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "parallelstore_v1beta_generated_Parallelstore_ListInstances_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "parallelstore_v1beta_generated_parallelstore_list_instances_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreAsyncClient", + "shortName": "ParallelstoreAsyncClient" + }, + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreAsyncClient.update_instance", + "method": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore.UpdateInstance", + "service": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore", + "shortName": "Parallelstore" + }, + "shortName": "UpdateInstance" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.parallelstore_v1beta.types.UpdateInstanceRequest" + }, + { + "name": "instance", + "type": "google.cloud.parallelstore_v1beta.types.Instance" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "update_instance" + }, + "description": "Sample for UpdateInstance", + "file": "parallelstore_v1beta_generated_parallelstore_update_instance_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "parallelstore_v1beta_generated_Parallelstore_UpdateInstance_async", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "parallelstore_v1beta_generated_parallelstore_update_instance_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreClient", + "shortName": "ParallelstoreClient" + }, + "fullName": "google.cloud.parallelstore_v1beta.ParallelstoreClient.update_instance", + "method": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore.UpdateInstance", + "service": { + "fullName": "google.cloud.parallelstore.v1beta.Parallelstore", + "shortName": "Parallelstore" + }, + "shortName": "UpdateInstance" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.parallelstore_v1beta.types.UpdateInstanceRequest" + }, + { + "name": "instance", + "type": "google.cloud.parallelstore_v1beta.types.Instance" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "update_instance" + }, + "description": "Sample for UpdateInstance", + "file": "parallelstore_v1beta_generated_parallelstore_update_instance_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "parallelstore_v1beta_generated_Parallelstore_UpdateInstance_sync", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "parallelstore_v1beta_generated_parallelstore_update_instance_sync.py" + } + ] +} diff --git a/packages/google-cloud-parallelstore/scripts/decrypt-secrets.sh b/packages/google-cloud-parallelstore/scripts/decrypt-secrets.sh new file mode 100755 index 000000000000..0018b421ddf8 --- /dev/null +++ b/packages/google-cloud-parallelstore/scripts/decrypt-secrets.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright 2023 Google LLC All rights reserved. +# +# 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. + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ROOT=$( dirname "$DIR" ) + +# Work from the project root. +cd $ROOT + +# Prevent it from overriding files. +# We recommend that sample authors use their own service account files and cloud project. +# In that case, they are supposed to prepare these files by themselves. +if [[ -f "testing/test-env.sh" ]] || \ + [[ -f "testing/service-account.json" ]] || \ + [[ -f "testing/client-secrets.json" ]]; then + echo "One or more target files exist, aborting." + exit 1 +fi + +# Use SECRET_MANAGER_PROJECT if set, fallback to cloud-devrel-kokoro-resources. +PROJECT_ID="${SECRET_MANAGER_PROJECT:-cloud-devrel-kokoro-resources}" + +gcloud secrets versions access latest --secret="python-docs-samples-test-env" \ + --project="${PROJECT_ID}" \ + > testing/test-env.sh +gcloud secrets versions access latest \ + --secret="python-docs-samples-service-account" \ + --project="${PROJECT_ID}" \ + > testing/service-account.json +gcloud secrets versions access latest \ + --secret="python-docs-samples-client-secrets" \ + --project="${PROJECT_ID}" \ + > testing/client-secrets.json diff --git a/packages/google-cloud-parallelstore/scripts/fixup_parallelstore_v1beta_keywords.py b/packages/google-cloud-parallelstore/scripts/fixup_parallelstore_v1beta_keywords.py new file mode 100644 index 000000000000..7750eb52b6f7 --- /dev/null +++ b/packages/google-cloud-parallelstore/scripts/fixup_parallelstore_v1beta_keywords.py @@ -0,0 +1,180 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +class parallelstoreCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'create_instance': ('parent', 'instance_id', 'instance', 'request_id', ), + 'delete_instance': ('name', 'request_id', ), + 'get_instance': ('name', ), + 'list_instances': ('parent', 'page_size', 'page_token', 'filter', 'order_by', ), + 'update_instance': ('update_mask', 'instance', 'request_id', ), + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=parallelstoreCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the parallelstore client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/packages/google-cloud-parallelstore/setup.py b/packages/google-cloud-parallelstore/setup.py new file mode 100644 index 000000000000..088a8aa47cb2 --- /dev/null +++ b/packages/google-cloud-parallelstore/setup.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import io +import os +import re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = "google-cloud-parallelstore" + + +description = "Google Cloud Parallelstore API client library" + +version = None + +with open( + os.path.join(package_root, "google/cloud/parallelstore/gapic_version.py") +) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert len(version_candidates) == 1 + version = version_candidates[0] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 1.34.1, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "google-auth >= 2.14.1, <3.0.0dev", + "proto-plus >= 1.22.3, <2.0.0dev", + "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-parallelstore" + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package + for package in setuptools.find_namespace_packages() + if package.startswith("google") +] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache 2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + install_requires=dependencies, + include_package_data=True, + zip_safe=False, +) diff --git a/packages/google-cloud-parallelstore/testing/.gitignore b/packages/google-cloud-parallelstore/testing/.gitignore new file mode 100644 index 000000000000..b05fbd630881 --- /dev/null +++ b/packages/google-cloud-parallelstore/testing/.gitignore @@ -0,0 +1,3 @@ +test-env.sh +service-account.json +client-secrets.json \ No newline at end of file diff --git a/packages/google-cloud-parallelstore/testing/constraints-3.10.txt b/packages/google-cloud-parallelstore/testing/constraints-3.10.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-cloud-parallelstore/testing/constraints-3.10.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-cloud-parallelstore/testing/constraints-3.11.txt b/packages/google-cloud-parallelstore/testing/constraints-3.11.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-cloud-parallelstore/testing/constraints-3.11.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-cloud-parallelstore/testing/constraints-3.12.txt b/packages/google-cloud-parallelstore/testing/constraints-3.12.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-cloud-parallelstore/testing/constraints-3.12.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-cloud-parallelstore/testing/constraints-3.7.txt b/packages/google-cloud-parallelstore/testing/constraints-3.7.txt new file mode 100644 index 000000000000..b8a550c73855 --- /dev/null +++ b/packages/google-cloud-parallelstore/testing/constraints-3.7.txt @@ -0,0 +1,10 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file. +# Pin the version to the lower bound. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", +# Then this file should have google-cloud-foo==1.14.0 +google-api-core==1.34.1 +google-auth==2.14.1 +proto-plus==1.22.3 +protobuf==3.19.5 diff --git a/packages/google-cloud-parallelstore/testing/constraints-3.8.txt b/packages/google-cloud-parallelstore/testing/constraints-3.8.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-cloud-parallelstore/testing/constraints-3.8.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-cloud-parallelstore/testing/constraints-3.9.txt b/packages/google-cloud-parallelstore/testing/constraints-3.9.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-cloud-parallelstore/testing/constraints-3.9.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-cloud-parallelstore/tests/__init__.py b/packages/google-cloud-parallelstore/tests/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-cloud-parallelstore/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-cloud-parallelstore/tests/unit/__init__.py b/packages/google-cloud-parallelstore/tests/unit/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-cloud-parallelstore/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-cloud-parallelstore/tests/unit/gapic/__init__.py b/packages/google-cloud-parallelstore/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-cloud-parallelstore/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-cloud-parallelstore/tests/unit/gapic/parallelstore_v1beta/__init__.py b/packages/google-cloud-parallelstore/tests/unit/gapic/parallelstore_v1beta/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-cloud-parallelstore/tests/unit/gapic/parallelstore_v1beta/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-cloud-parallelstore/tests/unit/gapic/parallelstore_v1beta/test_parallelstore.py b/packages/google-cloud-parallelstore/tests/unit/gapic/parallelstore_v1beta/test_parallelstore.py new file mode 100644 index 000000000000..d79c6b5d6738 --- /dev/null +++ b/packages/google-cloud-parallelstore/tests/unit/gapic/parallelstore_v1beta/test_parallelstore.py @@ -0,0 +1,6240 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import Iterable +import json +import math + +from google.api_core import ( + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) +from google.api_core import api_core_version, client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import operation_async # type: ignore +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import json_format +from google.protobuf import timestamp_pb2 # type: ignore +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +from google.cloud.parallelstore_v1beta.services.parallelstore import ( + ParallelstoreAsyncClient, + ParallelstoreClient, + pagers, + transports, +) +from google.cloud.parallelstore_v1beta.types import parallelstore + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ParallelstoreClient._get_default_mtls_endpoint(None) is None + assert ( + ParallelstoreClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + ParallelstoreClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + ParallelstoreClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ParallelstoreClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ParallelstoreClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + ) + + +def test__read_environment_variables(): + assert ParallelstoreClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ParallelstoreClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert ParallelstoreClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + ParallelstoreClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert ParallelstoreClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert ParallelstoreClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert ParallelstoreClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + ParallelstoreClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert ParallelstoreClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert ParallelstoreClient._get_client_cert_source(None, False) is None + assert ( + ParallelstoreClient._get_client_cert_source(mock_provided_cert_source, False) + is None + ) + assert ( + ParallelstoreClient._get_client_cert_source(mock_provided_cert_source, True) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + ParallelstoreClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + ParallelstoreClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + ParallelstoreClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ParallelstoreClient), +) +@mock.patch.object( + ParallelstoreAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ParallelstoreAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = ParallelstoreClient._DEFAULT_UNIVERSE + default_endpoint = ParallelstoreClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ParallelstoreClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + ParallelstoreClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + ParallelstoreClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == ParallelstoreClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ParallelstoreClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + ParallelstoreClient._get_api_endpoint(None, None, default_universe, "always") + == ParallelstoreClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ParallelstoreClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == ParallelstoreClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ParallelstoreClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + ParallelstoreClient._get_api_endpoint(None, None, default_universe, "never") + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + ParallelstoreClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + ParallelstoreClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + ParallelstoreClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + ParallelstoreClient._get_universe_domain(None, None) + == ParallelstoreClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + ParallelstoreClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ParallelstoreClient, transports.ParallelstoreGrpcTransport, "grpc"), + (ParallelstoreClient, transports.ParallelstoreRestTransport, "rest"), + ], +) +def test__validate_universe_domain(client_class, transport_class, transport_name): + client = client_class( + transport=transport_class(credentials=ga_credentials.AnonymousCredentials()) + ) + assert client._validate_universe_domain() == True + + # Test the case when universe is already validated. + assert client._validate_universe_domain() == True + + if transport_name == "grpc": + # Test the case where credentials are provided by the + # `local_channel_credentials`. The default universes in both match. + channel = grpc.secure_channel( + "http://localhost/", grpc.local_channel_credentials() + ) + client = client_class(transport=transport_class(channel=channel)) + assert client._validate_universe_domain() == True + + # Test the case where credentials do not exist: e.g. a transport is provided + # with no credentials. Validation should still succeed because there is no + # mismatch with non-existent credentials. + channel = grpc.secure_channel( + "http://localhost/", grpc.local_channel_credentials() + ) + transport = transport_class(channel=channel) + transport._credentials = None + client = client_class(transport=transport) + assert client._validate_universe_domain() == True + + # TODO: This is needed to cater for older versions of google-auth + # Make this test unconditional once the minimum supported version of + # google-auth becomes 2.23.0 or higher. + google_auth_major, google_auth_minor = [ + int(part) for part in google.auth.__version__.split(".")[0:2] + ] + if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): + credentials = ga_credentials.AnonymousCredentials() + credentials._universe_domain = "foo.com" + # Test the case when there is a universe mismatch from the credentials. + client = client_class(transport=transport_class(credentials=credentials)) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert ( + str(excinfo.value) + == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + ) + + # Test the case when there is a universe mismatch from the client. + # + # TODO: Make this test unconditional once the minimum supported version of + # google-api-core becomes 2.15.0 or higher. + api_core_major, api_core_minor = [ + int(part) for part in api_core_version.__version__.split(".")[0:2] + ] + if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): + client = client_class( + client_options={"universe_domain": "bar.com"}, + transport=transport_class( + credentials=ga_credentials.AnonymousCredentials(), + ), + ) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert ( + str(excinfo.value) + == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + ) + + # Test that ValueError is raised if universe_domain is provided via client options and credentials is None + with pytest.raises(ValueError): + client._compare_universes("foo.bar", None) + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ParallelstoreClient, "grpc"), + (ParallelstoreAsyncClient, "grpc_asyncio"), + (ParallelstoreClient, "rest"), + ], +) +def test_parallelstore_client_from_service_account_info(client_class, transport_name): + creds = ga_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, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "parallelstore.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://parallelstore.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.ParallelstoreGrpcTransport, "grpc"), + (transports.ParallelstoreGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ParallelstoreRestTransport, "rest"), + ], +) +def test_parallelstore_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ParallelstoreClient, "grpc"), + (ParallelstoreAsyncClient, "grpc_asyncio"), + (ParallelstoreClient, "rest"), + ], +) +def test_parallelstore_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "parallelstore.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://parallelstore.googleapis.com" + ) + + +def test_parallelstore_client_get_transport_class(): + transport = ParallelstoreClient.get_transport_class() + available_transports = [ + transports.ParallelstoreGrpcTransport, + transports.ParallelstoreRestTransport, + ] + assert transport in available_transports + + transport = ParallelstoreClient.get_transport_class("grpc") + assert transport == transports.ParallelstoreGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ParallelstoreClient, transports.ParallelstoreGrpcTransport, "grpc"), + ( + ParallelstoreAsyncClient, + transports.ParallelstoreGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (ParallelstoreClient, transports.ParallelstoreRestTransport, "rest"), + ], +) +@mock.patch.object( + ParallelstoreClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ParallelstoreClient), +) +@mock.patch.object( + ParallelstoreAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ParallelstoreAsyncClient), +) +def test_parallelstore_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ParallelstoreClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ParallelstoreClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (ParallelstoreClient, transports.ParallelstoreGrpcTransport, "grpc", "true"), + ( + ParallelstoreAsyncClient, + transports.ParallelstoreGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (ParallelstoreClient, transports.ParallelstoreGrpcTransport, "grpc", "false"), + ( + ParallelstoreAsyncClient, + transports.ParallelstoreGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + (ParallelstoreClient, transports.ParallelstoreRestTransport, "rest", "true"), + (ParallelstoreClient, transports.ParallelstoreRestTransport, "rest", "false"), + ], +) +@mock.patch.object( + ParallelstoreClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ParallelstoreClient), +) +@mock.patch.object( + ParallelstoreAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ParallelstoreAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_parallelstore_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + 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, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + 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=True, + ): + with mock.patch( + "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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + 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, + always_use_jwt_access=True, + api_audience=None, + ) + + # 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(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", [ParallelstoreClient, ParallelstoreAsyncClient] +) +@mock.patch.object( + ParallelstoreClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ParallelstoreClient), +) +@mock.patch.object( + ParallelstoreAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ParallelstoreAsyncClient), +) +def test_parallelstore_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize( + "client_class", [ParallelstoreClient, ParallelstoreAsyncClient] +) +@mock.patch.object( + ParallelstoreClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ParallelstoreClient), +) +@mock.patch.object( + ParallelstoreAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ParallelstoreAsyncClient), +) +def test_parallelstore_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = ParallelstoreClient._DEFAULT_UNIVERSE + default_endpoint = ParallelstoreClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ParallelstoreClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ParallelstoreClient, transports.ParallelstoreGrpcTransport, "grpc"), + ( + ParallelstoreAsyncClient, + transports.ParallelstoreGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (ParallelstoreClient, transports.ParallelstoreRestTransport, "rest"), + ], +) +def test_parallelstore_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + ParallelstoreClient, + transports.ParallelstoreGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + ParallelstoreAsyncClient, + transports.ParallelstoreGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + (ParallelstoreClient, transports.ParallelstoreRestTransport, "rest", None), + ], +) +def test_parallelstore_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_parallelstore_client_client_options_from_dict(): + with mock.patch( + "google.cloud.parallelstore_v1beta.services.parallelstore.transports.ParallelstoreGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = ParallelstoreClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + ParallelstoreClient, + transports.ParallelstoreGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + ParallelstoreAsyncClient, + transports.ParallelstoreGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_parallelstore_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "parallelstore.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=None, + default_host="parallelstore.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + parallelstore.ListInstancesRequest, + dict, + ], +) +def test_list_instances(request_type, transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_instances), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = parallelstore.ListInstancesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + response = client.list_instances(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.ListInstancesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListInstancesPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +def test_list_instances_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 = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_instances), "__call__") as call: + client.list_instances() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.ListInstancesRequest() + + +@pytest.mark.asyncio +async def test_list_instances_async( + transport: str = "grpc_asyncio", request_type=parallelstore.ListInstancesRequest +): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_instances), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + parallelstore.ListInstancesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + ) + response = await client.list_instances(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.ListInstancesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListInstancesAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +@pytest.mark.asyncio +async def test_list_instances_async_from_dict(): + await test_list_instances_async(request_type=dict) + + +def test_list_instances_field_headers(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = parallelstore.ListInstancesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_instances), "__call__") as call: + call.return_value = parallelstore.ListInstancesResponse() + client.list_instances(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_instances_field_headers_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = parallelstore.ListInstancesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_instances), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + parallelstore.ListInstancesResponse() + ) + await client.list_instances(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_instances_flattened(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_instances), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = parallelstore.ListInstancesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_instances( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_instances_flattened_error(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_instances( + parallelstore.ListInstancesRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_instances_flattened_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_instances), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = parallelstore.ListInstancesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + parallelstore.ListInstancesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_instances( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_instances_flattened_error_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_instances( + parallelstore.ListInstancesRequest(), + parent="parent_value", + ) + + +def test_list_instances_pager(transport_name: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_instances), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + parallelstore.Instance(), + parallelstore.Instance(), + ], + next_page_token="abc", + ), + parallelstore.ListInstancesResponse( + instances=[], + next_page_token="def", + ), + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + ], + next_page_token="ghi", + ), + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + parallelstore.Instance(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_instances(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, parallelstore.Instance) for i in results) + + +def test_list_instances_pages(transport_name: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_instances), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + parallelstore.Instance(), + parallelstore.Instance(), + ], + next_page_token="abc", + ), + parallelstore.ListInstancesResponse( + instances=[], + next_page_token="def", + ), + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + ], + next_page_token="ghi", + ), + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + parallelstore.Instance(), + ], + ), + RuntimeError, + ) + pages = list(client.list_instances(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_instances_async_pager(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_instances), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + parallelstore.Instance(), + parallelstore.Instance(), + ], + next_page_token="abc", + ), + parallelstore.ListInstancesResponse( + instances=[], + next_page_token="def", + ), + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + ], + next_page_token="ghi", + ), + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + parallelstore.Instance(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_instances( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, parallelstore.Instance) for i in responses) + + +@pytest.mark.asyncio +async def test_list_instances_async_pages(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_instances), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + parallelstore.Instance(), + parallelstore.Instance(), + ], + next_page_token="abc", + ), + parallelstore.ListInstancesResponse( + instances=[], + next_page_token="def", + ), + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + ], + next_page_token="ghi", + ), + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + parallelstore.Instance(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_instances(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + parallelstore.GetInstanceRequest, + dict, + ], +) +def test_get_instance(request_type, transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = parallelstore.Instance( + name="name_value", + description="description_value", + state=parallelstore.Instance.State.CREATING, + capacity_gib=1247, + daos_version="daos_version_value", + access_points=["access_points_value"], + network="network_value", + reserved_ip_range="reserved_ip_range_value", + ) + response = client.get_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.GetInstanceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, parallelstore.Instance) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.state == parallelstore.Instance.State.CREATING + assert response.capacity_gib == 1247 + assert response.daos_version == "daos_version_value" + assert response.access_points == ["access_points_value"] + assert response.network == "network_value" + assert response.reserved_ip_range == "reserved_ip_range_value" + + +def test_get_instance_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 = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_instance), "__call__") as call: + client.get_instance() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.GetInstanceRequest() + + +@pytest.mark.asyncio +async def test_get_instance_async( + transport: str = "grpc_asyncio", request_type=parallelstore.GetInstanceRequest +): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + parallelstore.Instance( + name="name_value", + description="description_value", + state=parallelstore.Instance.State.CREATING, + capacity_gib=1247, + daos_version="daos_version_value", + access_points=["access_points_value"], + network="network_value", + reserved_ip_range="reserved_ip_range_value", + ) + ) + response = await client.get_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.GetInstanceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, parallelstore.Instance) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.state == parallelstore.Instance.State.CREATING + assert response.capacity_gib == 1247 + assert response.daos_version == "daos_version_value" + assert response.access_points == ["access_points_value"] + assert response.network == "network_value" + assert response.reserved_ip_range == "reserved_ip_range_value" + + +@pytest.mark.asyncio +async def test_get_instance_async_from_dict(): + await test_get_instance_async(request_type=dict) + + +def test_get_instance_field_headers(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = parallelstore.GetInstanceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_instance), "__call__") as call: + call.return_value = parallelstore.Instance() + client.get_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_instance_field_headers_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = parallelstore.GetInstanceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_instance), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + parallelstore.Instance() + ) + await client.get_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_instance_flattened(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = parallelstore.Instance() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_instance( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_instance_flattened_error(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_instance( + parallelstore.GetInstanceRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_instance_flattened_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = parallelstore.Instance() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + parallelstore.Instance() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_instance( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_instance_flattened_error_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_instance( + parallelstore.GetInstanceRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + parallelstore.CreateInstanceRequest, + dict, + ], +) +def test_create_instance(request_type, transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.CreateInstanceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_instance_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 = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_instance), "__call__") as call: + client.create_instance() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.CreateInstanceRequest() + + +@pytest.mark.asyncio +async def test_create_instance_async( + transport: str = "grpc_asyncio", request_type=parallelstore.CreateInstanceRequest +): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.CreateInstanceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_instance_async_from_dict(): + await test_create_instance_async(request_type=dict) + + +def test_create_instance_field_headers(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = parallelstore.CreateInstanceRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_instance), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_instance_field_headers_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = parallelstore.CreateInstanceRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_instance), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.create_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_create_instance_flattened(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_instance( + parent="parent_value", + instance=parallelstore.Instance(name="name_value"), + instance_id="instance_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].instance + mock_val = parallelstore.Instance(name="name_value") + assert arg == mock_val + arg = args[0].instance_id + mock_val = "instance_id_value" + assert arg == mock_val + + +def test_create_instance_flattened_error(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_instance( + parallelstore.CreateInstanceRequest(), + parent="parent_value", + instance=parallelstore.Instance(name="name_value"), + instance_id="instance_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_instance_flattened_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_instance( + parent="parent_value", + instance=parallelstore.Instance(name="name_value"), + instance_id="instance_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].instance + mock_val = parallelstore.Instance(name="name_value") + assert arg == mock_val + arg = args[0].instance_id + mock_val = "instance_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_instance_flattened_error_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_instance( + parallelstore.CreateInstanceRequest(), + parent="parent_value", + instance=parallelstore.Instance(name="name_value"), + instance_id="instance_id_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + parallelstore.UpdateInstanceRequest, + dict, + ], +) +def test_update_instance(request_type, transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.update_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.UpdateInstanceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_update_instance_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 = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_instance), "__call__") as call: + client.update_instance() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.UpdateInstanceRequest() + + +@pytest.mark.asyncio +async def test_update_instance_async( + transport: str = "grpc_asyncio", request_type=parallelstore.UpdateInstanceRequest +): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.update_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.UpdateInstanceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_update_instance_async_from_dict(): + await test_update_instance_async(request_type=dict) + + +def test_update_instance_field_headers(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = parallelstore.UpdateInstanceRequest() + + request.instance.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_instance), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "instance.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_instance_field_headers_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = parallelstore.UpdateInstanceRequest() + + request.instance.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_instance), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.update_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "instance.name=name_value", + ) in kw["metadata"] + + +def test_update_instance_flattened(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_instance( + instance=parallelstore.Instance(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].instance + mock_val = parallelstore.Instance(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_instance_flattened_error(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_instance( + parallelstore.UpdateInstanceRequest(), + instance=parallelstore.Instance(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_instance_flattened_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_instance( + instance=parallelstore.Instance(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].instance + mock_val = parallelstore.Instance(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_instance_flattened_error_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_instance( + parallelstore.UpdateInstanceRequest(), + instance=parallelstore.Instance(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + parallelstore.DeleteInstanceRequest, + dict, + ], +) +def test_delete_instance(request_type, transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.DeleteInstanceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_instance_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 = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_instance), "__call__") as call: + client.delete_instance() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.DeleteInstanceRequest() + + +@pytest.mark.asyncio +async def test_delete_instance_async( + transport: str = "grpc_asyncio", request_type=parallelstore.DeleteInstanceRequest +): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.delete_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == parallelstore.DeleteInstanceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_delete_instance_async_from_dict(): + await test_delete_instance_async(request_type=dict) + + +def test_delete_instance_field_headers(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = parallelstore.DeleteInstanceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_instance), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_instance_field_headers_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = parallelstore.DeleteInstanceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_instance), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_instance(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_instance_flattened(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_instance( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_instance_flattened_error(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_instance( + parallelstore.DeleteInstanceRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_instance_flattened_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_instance), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_instance( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_instance_flattened_error_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_instance( + parallelstore.DeleteInstanceRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + parallelstore.ListInstancesRequest, + dict, + ], +) +def test_list_instances_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = parallelstore.ListInstancesResponse( + next_page_token="next_page_token_value", + unreachable=["unreachable_value"], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = parallelstore.ListInstancesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_instances(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListInstancesPager) + assert response.next_page_token == "next_page_token_value" + assert response.unreachable == ["unreachable_value"] + + +def test_list_instances_rest_required_fields( + request_type=parallelstore.ListInstancesRequest, +): + transport_class = transports.ParallelstoreRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_instances._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_instances._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = parallelstore.ListInstancesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = parallelstore.ListInstancesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_instances(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_instances_rest_unset_required_fields(): + transport = transports.ParallelstoreRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_instances._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_instances_rest_interceptors(null_interceptor): + transport = transports.ParallelstoreRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ParallelstoreRestInterceptor(), + ) + client = ParallelstoreClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ParallelstoreRestInterceptor, "post_list_instances" + ) as post, mock.patch.object( + transports.ParallelstoreRestInterceptor, "pre_list_instances" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = parallelstore.ListInstancesRequest.pb( + parallelstore.ListInstancesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = parallelstore.ListInstancesResponse.to_json( + parallelstore.ListInstancesResponse() + ) + + request = parallelstore.ListInstancesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = parallelstore.ListInstancesResponse() + + client.list_instances( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_instances_rest_bad_request( + transport: str = "rest", request_type=parallelstore.ListInstancesRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_instances(request) + + +def test_list_instances_rest_flattened(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = parallelstore.ListInstancesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = parallelstore.ListInstancesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_instances(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{parent=projects/*/locations/*}/instances" + % client.transport._host, + args[1], + ) + + +def test_list_instances_rest_flattened_error(transport: str = "rest"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_instances( + parallelstore.ListInstancesRequest(), + parent="parent_value", + ) + + +def test_list_instances_rest_pager(transport: str = "rest"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + parallelstore.Instance(), + parallelstore.Instance(), + ], + next_page_token="abc", + ), + parallelstore.ListInstancesResponse( + instances=[], + next_page_token="def", + ), + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + ], + next_page_token="ghi", + ), + parallelstore.ListInstancesResponse( + instances=[ + parallelstore.Instance(), + parallelstore.Instance(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + parallelstore.ListInstancesResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_instances(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, parallelstore.Instance) for i in results) + + pages = list(client.list_instances(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + parallelstore.GetInstanceRequest, + dict, + ], +) +def test_get_instance_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = parallelstore.Instance( + name="name_value", + description="description_value", + state=parallelstore.Instance.State.CREATING, + capacity_gib=1247, + daos_version="daos_version_value", + access_points=["access_points_value"], + network="network_value", + reserved_ip_range="reserved_ip_range_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = parallelstore.Instance.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_instance(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, parallelstore.Instance) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.state == parallelstore.Instance.State.CREATING + assert response.capacity_gib == 1247 + assert response.daos_version == "daos_version_value" + assert response.access_points == ["access_points_value"] + assert response.network == "network_value" + assert response.reserved_ip_range == "reserved_ip_range_value" + + +def test_get_instance_rest_required_fields( + request_type=parallelstore.GetInstanceRequest, +): + transport_class = transports.ParallelstoreRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_instance._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_instance._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = parallelstore.Instance() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = parallelstore.Instance.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_instance(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_instance_rest_unset_required_fields(): + transport = transports.ParallelstoreRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_instance._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_instance_rest_interceptors(null_interceptor): + transport = transports.ParallelstoreRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ParallelstoreRestInterceptor(), + ) + client = ParallelstoreClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ParallelstoreRestInterceptor, "post_get_instance" + ) as post, mock.patch.object( + transports.ParallelstoreRestInterceptor, "pre_get_instance" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = parallelstore.GetInstanceRequest.pb( + parallelstore.GetInstanceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = parallelstore.Instance.to_json( + parallelstore.Instance() + ) + + request = parallelstore.GetInstanceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = parallelstore.Instance() + + client.get_instance( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_instance_rest_bad_request( + transport: str = "rest", request_type=parallelstore.GetInstanceRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_instance(request) + + +def test_get_instance_rest_flattened(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = parallelstore.Instance() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/instances/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = parallelstore.Instance.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_instance(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{name=projects/*/locations/*/instances/*}" + % client.transport._host, + args[1], + ) + + +def test_get_instance_rest_flattened_error(transport: str = "rest"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_instance( + parallelstore.GetInstanceRequest(), + name="name_value", + ) + + +def test_get_instance_rest_error(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + parallelstore.CreateInstanceRequest, + dict, + ], +) +def test_create_instance_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["instance"] = { + "name": "name_value", + "description": "description_value", + "state": 1, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "labels": {}, + "capacity_gib": 1247, + "daos_version": "daos_version_value", + "access_points": ["access_points_value1", "access_points_value2"], + "network": "network_value", + "reserved_ip_range": "reserved_ip_range_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = parallelstore.CreateInstanceRequest.meta.fields["instance"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["instance"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["instance"][field])): + del request_init["instance"][field][i][subfield] + else: + del request_init["instance"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_instance(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_create_instance_rest_required_fields( + request_type=parallelstore.CreateInstanceRequest, +): + transport_class = transports.ParallelstoreRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["instance_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "instanceId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_instance._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "instanceId" in jsonified_request + assert jsonified_request["instanceId"] == request_init["instance_id"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["instanceId"] = "instance_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_instance._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "instance_id", + "request_id", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "instanceId" in jsonified_request + assert jsonified_request["instanceId"] == "instance_id_value" + + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_instance(request) + + expected_params = [ + ( + "instanceId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_instance_rest_unset_required_fields(): + transport = transports.ParallelstoreRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_instance._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "instanceId", + "requestId", + ) + ) + & set( + ( + "parent", + "instanceId", + "instance", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_instance_rest_interceptors(null_interceptor): + transport = transports.ParallelstoreRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ParallelstoreRestInterceptor(), + ) + client = ParallelstoreClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.ParallelstoreRestInterceptor, "post_create_instance" + ) as post, mock.patch.object( + transports.ParallelstoreRestInterceptor, "pre_create_instance" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = parallelstore.CreateInstanceRequest.pb( + parallelstore.CreateInstanceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = parallelstore.CreateInstanceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.create_instance( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_instance_rest_bad_request( + transport: str = "rest", request_type=parallelstore.CreateInstanceRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_instance(request) + + +def test_create_instance_rest_flattened(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + instance=parallelstore.Instance(name="name_value"), + instance_id="instance_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_instance(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{parent=projects/*/locations/*}/instances" + % client.transport._host, + args[1], + ) + + +def test_create_instance_rest_flattened_error(transport: str = "rest"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_instance( + parallelstore.CreateInstanceRequest(), + parent="parent_value", + instance=parallelstore.Instance(name="name_value"), + instance_id="instance_id_value", + ) + + +def test_create_instance_rest_error(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + parallelstore.UpdateInstanceRequest, + dict, + ], +) +def test_update_instance_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "instance": {"name": "projects/sample1/locations/sample2/instances/sample3"} + } + request_init["instance"] = { + "name": "projects/sample1/locations/sample2/instances/sample3", + "description": "description_value", + "state": 1, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "labels": {}, + "capacity_gib": 1247, + "daos_version": "daos_version_value", + "access_points": ["access_points_value1", "access_points_value2"], + "network": "network_value", + "reserved_ip_range": "reserved_ip_range_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = parallelstore.UpdateInstanceRequest.meta.fields["instance"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["instance"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["instance"][field])): + del request_init["instance"][field][i][subfield] + else: + del request_init["instance"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_instance(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_update_instance_rest_required_fields( + request_type=parallelstore.UpdateInstanceRequest, +): + transport_class = transports.ParallelstoreRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_instance._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_instance._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "request_id", + "update_mask", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_instance(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_instance_rest_unset_required_fields(): + transport = transports.ParallelstoreRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_instance._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "requestId", + "updateMask", + ) + ) + & set( + ( + "updateMask", + "instance", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_instance_rest_interceptors(null_interceptor): + transport = transports.ParallelstoreRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ParallelstoreRestInterceptor(), + ) + client = ParallelstoreClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.ParallelstoreRestInterceptor, "post_update_instance" + ) as post, mock.patch.object( + transports.ParallelstoreRestInterceptor, "pre_update_instance" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = parallelstore.UpdateInstanceRequest.pb( + parallelstore.UpdateInstanceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = parallelstore.UpdateInstanceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.update_instance( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_instance_rest_bad_request( + transport: str = "rest", request_type=parallelstore.UpdateInstanceRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "instance": {"name": "projects/sample1/locations/sample2/instances/sample3"} + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_instance(request) + + +def test_update_instance_rest_flattened(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "instance": {"name": "projects/sample1/locations/sample2/instances/sample3"} + } + + # get truthy value for each flattened field + mock_args = dict( + instance=parallelstore.Instance(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_instance(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{instance.name=projects/*/locations/*/instances/*}" + % client.transport._host, + args[1], + ) + + +def test_update_instance_rest_flattened_error(transport: str = "rest"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_instance( + parallelstore.UpdateInstanceRequest(), + instance=parallelstore.Instance(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_instance_rest_error(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + parallelstore.DeleteInstanceRequest, + dict, + ], +) +def test_delete_instance_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_instance(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_delete_instance_rest_required_fields( + request_type=parallelstore.DeleteInstanceRequest, +): + transport_class = transports.ParallelstoreRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_instance._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_instance._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("request_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_instance(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_instance_rest_unset_required_fields(): + transport = transports.ParallelstoreRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_instance._get_unset_required_fields({}) + assert set(unset_fields) == (set(("requestId",)) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_instance_rest_interceptors(null_interceptor): + transport = transports.ParallelstoreRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ParallelstoreRestInterceptor(), + ) + client = ParallelstoreClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.ParallelstoreRestInterceptor, "post_delete_instance" + ) as post, mock.patch.object( + transports.ParallelstoreRestInterceptor, "pre_delete_instance" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = parallelstore.DeleteInstanceRequest.pb( + parallelstore.DeleteInstanceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = parallelstore.DeleteInstanceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.delete_instance( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_instance_rest_bad_request( + transport: str = "rest", request_type=parallelstore.DeleteInstanceRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/instances/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_instance(request) + + +def test_delete_instance_rest_flattened(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/instances/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_instance(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1beta/{name=projects/*/locations/*/instances/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_instance_rest_flattened_error(transport: str = "rest"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_instance( + parallelstore.DeleteInstanceRequest(), + name="name_value", + ) + + +def test_delete_instance_rest_error(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ParallelstoreGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ParallelstoreGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ParallelstoreClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ParallelstoreGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ParallelstoreClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ParallelstoreClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ParallelstoreGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ParallelstoreClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ParallelstoreGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ParallelstoreClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ParallelstoreGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ParallelstoreGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ParallelstoreGrpcTransport, + transports.ParallelstoreGrpcAsyncIOTransport, + transports.ParallelstoreRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "rest", + ], +) +def test_transport_kind(transport_name): + transport = ParallelstoreClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ParallelstoreGrpcTransport, + ) + + +def test_parallelstore_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ParallelstoreTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_parallelstore_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.parallelstore_v1beta.services.parallelstore.transports.ParallelstoreTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ParallelstoreTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "list_instances", + "get_instance", + "create_instance", + "update_instance", + "delete_instance", + "get_location", + "list_locations", + "get_operation", + "cancel_operation", + "delete_operation", + "list_operations", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_parallelstore_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.parallelstore_v1beta.services.parallelstore.transports.ParallelstoreTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ParallelstoreTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_parallelstore_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.cloud.parallelstore_v1beta.services.parallelstore.transports.ParallelstoreTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ParallelstoreTransport() + adc.assert_called_once() + + +def test_parallelstore_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ParallelstoreClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ParallelstoreGrpcTransport, + transports.ParallelstoreGrpcAsyncIOTransport, + ], +) +def test_parallelstore_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ParallelstoreGrpcTransport, + transports.ParallelstoreGrpcAsyncIOTransport, + transports.ParallelstoreRestTransport, + ], +) +def test_parallelstore_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ParallelstoreGrpcTransport, grpc_helpers), + (transports.ParallelstoreGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_parallelstore_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "parallelstore.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="parallelstore.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ParallelstoreGrpcTransport, + transports.ParallelstoreGrpcAsyncIOTransport, + ], +) +def test_parallelstore_grpc_transport_client_cert_source_for_mtls(transport_class): + cred = ga_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=None, + 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_parallelstore_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.ParallelstoreRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_parallelstore_rest_lro_client(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_parallelstore_host_no_port(transport_name): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="parallelstore.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "parallelstore.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://parallelstore.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_parallelstore_host_with_port(transport_name): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="parallelstore.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "parallelstore.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://parallelstore.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_parallelstore_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ParallelstoreClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ParallelstoreClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.list_instances._session + session2 = client2.transport.list_instances._session + assert session1 != session2 + session1 = client1.transport.get_instance._session + session2 = client2.transport.get_instance._session + assert session1 != session2 + session1 = client1.transport.create_instance._session + session2 = client2.transport.create_instance._session + assert session1 != session2 + session1 = client1.transport.update_instance._session + session2 = client2.transport.update_instance._session + assert session1 != session2 + session1 = client1.transport.delete_instance._session + session2 = client2.transport.delete_instance._session + assert session1 != session2 + + +def test_parallelstore_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ParallelstoreGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_parallelstore_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ParallelstoreGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + 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", + [ + transports.ParallelstoreGrpcTransport, + transports.ParallelstoreGrpcAsyncIOTransport, + ], +) +def test_parallelstore_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + 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", + [ + transports.ParallelstoreGrpcTransport, + transports.ParallelstoreGrpcAsyncIOTransport, + ], +) +def test_parallelstore_transport_channel_mtls_with_adc(transport_class): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_parallelstore_grpc_lro_client(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_parallelstore_grpc_lro_async_client(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_address_path(): + project = "squid" + region = "clam" + address = "whelk" + expected = "projects/{project}/regions/{region}/addresses/{address}".format( + project=project, + region=region, + address=address, + ) + actual = ParallelstoreClient.address_path(project, region, address) + assert expected == actual + + +def test_parse_address_path(): + expected = { + "project": "octopus", + "region": "oyster", + "address": "nudibranch", + } + path = ParallelstoreClient.address_path(**expected) + + # Check that the path construction is reversible. + actual = ParallelstoreClient.parse_address_path(path) + assert expected == actual + + +def test_instance_path(): + project = "cuttlefish" + location = "mussel" + instance = "winkle" + expected = "projects/{project}/locations/{location}/instances/{instance}".format( + project=project, + location=location, + instance=instance, + ) + actual = ParallelstoreClient.instance_path(project, location, instance) + assert expected == actual + + +def test_parse_instance_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "instance": "abalone", + } + path = ParallelstoreClient.instance_path(**expected) + + # Check that the path construction is reversible. + actual = ParallelstoreClient.parse_instance_path(path) + assert expected == actual + + +def test_network_path(): + project = "squid" + network = "clam" + expected = "projects/{project}/global/networks/{network}".format( + project=project, + network=network, + ) + actual = ParallelstoreClient.network_path(project, network) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "project": "whelk", + "network": "octopus", + } + path = ParallelstoreClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = ParallelstoreClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "oyster" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = ParallelstoreClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = ParallelstoreClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ParallelstoreClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "cuttlefish" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = ParallelstoreClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = ParallelstoreClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ParallelstoreClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "winkle" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = ParallelstoreClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = ParallelstoreClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ParallelstoreClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "scallop" + expected = "projects/{project}".format( + project=project, + ) + actual = ParallelstoreClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = ParallelstoreClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ParallelstoreClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "squid" + location = "clam" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = ParallelstoreClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = ParallelstoreClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ParallelstoreClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.ParallelstoreTransport, "_prep_wrapped_messages" + ) as prep: + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.ParallelstoreTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = ParallelstoreClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_get_location_rest_bad_request( + transport: str = "rest", request_type=locations_pb2.GetLocationRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_location(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.GetLocationRequest, + dict, + ], +) +def test_get_location_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = locations_pb2.Location() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_location(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_list_locations_rest_bad_request( + transport: str = "rest", request_type=locations_pb2.ListLocationsRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({"name": "projects/sample1"}, request) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_locations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.ListLocationsRequest, + dict, + ], +) +def test_list_locations_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = locations_pb2.ListLocationsResponse() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_locations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_cancel_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.CancelOperationRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.cancel_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.CancelOperationRequest, + dict, + ], +) +def test_cancel_operation_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2/operations/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "{}" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.cancel_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.DeleteOperationRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.DeleteOperationRequest, + dict, + ], +) +def test_delete_operation_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2/operations/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "{}" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_get_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.GetOperationRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2/operations/sample3"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.ListOperationsRequest +): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_delete_operation(transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_operation_async(transport: str = "grpc_asyncio"): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_field_headers(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = None + + client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_operation_field_headers_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_delete_operation_from_dict(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_delete_operation_from_dict_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_cancel_operation(transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_cancel_operation_async(transport: str = "grpc_asyncio"): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_cancel_operation_field_headers(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = None + + client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_cancel_operation_field_headers_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_cancel_operation_from_dict(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_cancel_operation_from_dict_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_operation(transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc_asyncio"): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc_asyncio"): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_locations(transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + response = client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +@pytest.mark.asyncio +async def test_list_locations_async(transport: str = "grpc_asyncio"): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_list_locations_field_headers(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = locations_pb2.ListLocationsResponse() + + client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_locations_field_headers_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + await client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_locations_from_dict(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + + response = client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_locations_from_dict_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_location(transport: str = "grpc"): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + response = client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +@pytest.mark.asyncio +async def test_get_location_async(transport: str = "grpc_asyncio"): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_get_location_field_headers(): + client = ParallelstoreClient(credentials=ga_credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = locations_pb2.Location() + + client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations/abc", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_location_field_headers_async(): + client = ParallelstoreAsyncClient(credentials=ga_credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + await client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations/abc", + ) in kw["metadata"] + + +def test_get_location_from_dict(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + + response = client.get_location( + request={ + "name": "locations/abc", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_location_from_dict_async(): + client = ParallelstoreAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = ParallelstoreClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (ParallelstoreClient, transports.ParallelstoreGrpcTransport), + (ParallelstoreAsyncClient, transports.ParallelstoreGrpcAsyncIOTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) From ec4508aa3b41e3c9c720f06073c853bdbc62c142 Mon Sep 17 00:00:00 2001 From: yoshi-code-bot <70984784+yoshi-code-bot@users.noreply.github.com> Date: Thu, 29 Feb 2024 10:45:11 -0800 Subject: [PATCH 05/13] chore: Update release-please config files (#12373) Update release-please config files --- .release-please-manifest.json | 1 + release-please-config.json | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 5d7d68e6a24d..6f428eaa2e2f 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -109,6 +109,7 @@ "packages/google-cloud-orchestration-airflow": "1.12.0", "packages/google-cloud-os-config": "1.17.2", "packages/google-cloud-os-login": "2.14.2", + "packages/google-cloud-parallelstore": "0.0.0", "packages/google-cloud-phishing-protection": "1.11.2", "packages/google-cloud-policy-troubleshooter": "1.11.2", "packages/google-cloud-policysimulator": "0.1.5", diff --git a/release-please-config.json b/release-please-config.json index b2337a569b93..afa3f6ef0358 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -1901,6 +1901,21 @@ ], "release-type": "python" }, + "packages/google-cloud-parallelstore": { + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "component": "google-cloud-parallelstore", + "extra-files": [ + "google/cloud/parallelstore/gapic_version.py", + "google/cloud/parallelstore_v1beta/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.parallelstore.v1beta.json", + "type": "json" + } + ], + "release-type": "python" + }, "packages/google-cloud-phishing-protection": { "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, From 542c38cc20728622d9434db48fecd2e2af620a06 Mon Sep 17 00:00:00 2001 From: "owlbot-bootstrapper[bot]" <104649659+owlbot-bootstrapper[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 19:45:06 +0000 Subject: [PATCH 06/13] feat: add initial files for google.apps.events.subscriptions.v1 (#12374) Source-Link: https://github.com/googleapis/googleapis-gen/commit/01518d8fd1e17facedcba2fe8e6bc2856145b957 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWFwcHMtZXZlbnRzLXN1YnNjcmlwdGlvbnMvLk93bEJvdC55YW1sIiwiaCI6IjAxNTE4ZDhmZDFlMTdmYWNlZGNiYTJmZThlNmJjMjg1NjE0NWI5NTcifQ== PiperOrigin-RevId: 0 --------- Co-authored-by: Owlbot Bootstrapper Co-authored-by: Owl Bot Co-authored-by: Anthonios Partheniou --- .../.OwlBot.yaml | 18 + .../.coveragerc | 13 + .../google-apps-events-subscriptions/.flake8 | 33 + .../.gitignore | 63 + .../.repo-metadata.json | 17 + .../CHANGELOG.md | 1 + .../CODE_OF_CONDUCT.md | 95 + .../CONTRIBUTING.rst | 271 + .../google-apps-events-subscriptions/LICENSE | 202 + .../MANIFEST.in | 25 + .../README.rst | 108 + .../docs/CHANGELOG.md | 1 + .../docs/README.rst | 1 + .../docs/_static/custom.css | 20 + .../docs/_templates/layout.html | 50 + .../docs/conf.py | 384 ++ .../events_subscriptions_v1/services_.rst | 6 + .../subscriptions_service.rst | 10 + .../docs/events_subscriptions_v1/types_.rst | 6 + .../docs/index.rst | 23 + .../docs/multiprocessing.rst | 7 + .../apps/events_subscriptions/__init__.py | 63 + .../events_subscriptions/gapic_version.py | 16 + .../google/apps/events_subscriptions/py.typed | 2 + .../apps/events_subscriptions_v1/__init__.py | 61 + .../gapic_metadata.json | 118 + .../events_subscriptions_v1/gapic_version.py | 16 + .../apps/events_subscriptions_v1/py.typed | 2 + .../services/__init__.py | 15 + .../subscriptions_service/__init__.py | 22 + .../subscriptions_service/async_client.py | 1189 ++++ .../services/subscriptions_service/client.py | 1609 +++++ .../services/subscriptions_service/pagers.py | 162 + .../transports/__init__.py | 38 + .../subscriptions_service/transports/base.py | 283 + .../subscriptions_service/transports/grpc.py | 462 ++ .../transports/grpc_asyncio.py | 467 ++ .../subscriptions_service/transports/rest.py | 1132 ++++ .../events_subscriptions_v1/types/__init__.py | 46 + .../types/subscription_resource.py | 353 + .../types/subscriptions_service.py | 297 + .../google-apps-events-subscriptions/mypy.ini | 3 + .../noxfile.py | 428 ++ ...a_google.apps.events.subscriptions.v1.json | 1005 +++ ...tions_service_create_subscription_async.py | 61 + ...ptions_service_create_subscription_sync.py | 61 + ...tions_service_delete_subscription_async.py | 56 + ...ptions_service_delete_subscription_sync.py | 56 + ...riptions_service_get_subscription_async.py | 52 + ...criptions_service_get_subscription_sync.py | 52 + ...ptions_service_list_subscriptions_async.py | 53 + ...iptions_service_list_subscriptions_sync.py | 53 + ...s_service_reactivate_subscription_async.py | 56 + ...ns_service_reactivate_subscription_sync.py | 56 + ...tions_service_update_subscription_async.py | 61 + ...ptions_service_update_subscription_sync.py | 61 + .../scripts/decrypt-secrets.sh | 46 + .../fixup_events_subscriptions_v1_keywords.py | 181 + .../google-apps-events-subscriptions/setup.py | 93 + .../testing/.gitignore | 3 + .../testing/constraints-3.10.txt | 6 + .../testing/constraints-3.11.txt | 6 + .../testing/constraints-3.12.txt | 6 + .../testing/constraints-3.7.txt | 10 + .../testing/constraints-3.8.txt | 6 + .../testing/constraints-3.9.txt | 6 + .../tests/__init__.py | 15 + .../tests/unit/__init__.py | 15 + .../tests/unit/gapic/__init__.py | 15 + .../gapic/events_subscriptions_v1/__init__.py | 15 + .../test_subscriptions_service.py | 5833 +++++++++++++++++ 71 files changed, 16077 insertions(+) create mode 100644 packages/google-apps-events-subscriptions/.OwlBot.yaml create mode 100644 packages/google-apps-events-subscriptions/.coveragerc create mode 100644 packages/google-apps-events-subscriptions/.flake8 create mode 100644 packages/google-apps-events-subscriptions/.gitignore create mode 100644 packages/google-apps-events-subscriptions/.repo-metadata.json create mode 100644 packages/google-apps-events-subscriptions/CHANGELOG.md create mode 100644 packages/google-apps-events-subscriptions/CODE_OF_CONDUCT.md create mode 100644 packages/google-apps-events-subscriptions/CONTRIBUTING.rst create mode 100644 packages/google-apps-events-subscriptions/LICENSE create mode 100644 packages/google-apps-events-subscriptions/MANIFEST.in create mode 100644 packages/google-apps-events-subscriptions/README.rst create mode 120000 packages/google-apps-events-subscriptions/docs/CHANGELOG.md create mode 120000 packages/google-apps-events-subscriptions/docs/README.rst create mode 100644 packages/google-apps-events-subscriptions/docs/_static/custom.css create mode 100644 packages/google-apps-events-subscriptions/docs/_templates/layout.html create mode 100644 packages/google-apps-events-subscriptions/docs/conf.py create mode 100644 packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/services_.rst create mode 100644 packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/subscriptions_service.rst create mode 100644 packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/types_.rst create mode 100644 packages/google-apps-events-subscriptions/docs/index.rst create mode 100644 packages/google-apps-events-subscriptions/docs/multiprocessing.rst create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions/__init__.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions/gapic_version.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions/py.typed create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_metadata.json create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_version.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/py.typed create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/__init__.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/__init__.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/async_client.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/client.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/pagers.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/__init__.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/base.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc_asyncio.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/rest.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/__init__.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscription_resource.py create mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscriptions_service.py create mode 100644 packages/google-apps-events-subscriptions/mypy.ini create mode 100644 packages/google-apps-events-subscriptions/noxfile.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py create mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py create mode 100755 packages/google-apps-events-subscriptions/scripts/decrypt-secrets.sh create mode 100644 packages/google-apps-events-subscriptions/scripts/fixup_events_subscriptions_v1_keywords.py create mode 100644 packages/google-apps-events-subscriptions/setup.py create mode 100644 packages/google-apps-events-subscriptions/testing/.gitignore create mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.10.txt create mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.11.txt create mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.12.txt create mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.7.txt create mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.8.txt create mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.9.txt create mode 100644 packages/google-apps-events-subscriptions/tests/__init__.py create mode 100644 packages/google-apps-events-subscriptions/tests/unit/__init__.py create mode 100644 packages/google-apps-events-subscriptions/tests/unit/gapic/__init__.py create mode 100644 packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/__init__.py create mode 100644 packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/test_subscriptions_service.py diff --git a/packages/google-apps-events-subscriptions/.OwlBot.yaml b/packages/google-apps-events-subscriptions/.OwlBot.yaml new file mode 100644 index 000000000000..b29ae76b745b --- /dev/null +++ b/packages/google-apps-events-subscriptions/.OwlBot.yaml @@ -0,0 +1,18 @@ +# Copyright 2022 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. + +deep-copy-regex: + - source: /google/apps/events/subscriptions/(v.*)/.*-py + dest: /owl-bot-staging/google-apps-events-subscriptions/$1 +api-name: google-apps-events-subscriptions diff --git a/packages/google-apps-events-subscriptions/.coveragerc b/packages/google-apps-events-subscriptions/.coveragerc new file mode 100644 index 000000000000..f7786672c12c --- /dev/null +++ b/packages/google-apps-events-subscriptions/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/apps/events_subscriptions/__init__.py + google/apps/events_subscriptions/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/packages/google-apps-events-subscriptions/.flake8 b/packages/google-apps-events-subscriptions/.flake8 new file mode 100644 index 000000000000..87f6e408c47d --- /dev/null +++ b/packages/google-apps-events-subscriptions/.flake8 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2023 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. + +# Generated by synthtool. DO NOT EDIT! +[flake8] +ignore = E203, E231, E266, E501, W503 +exclude = + # Exclude generated code. + **/proto/** + **/gapic/** + **/services/** + **/types/** + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/packages/google-apps-events-subscriptions/.gitignore b/packages/google-apps-events-subscriptions/.gitignore new file mode 100644 index 000000000000..b4243ced74e4 --- /dev/null +++ b/packages/google-apps-events-subscriptions/.gitignore @@ -0,0 +1,63 @@ +*.py[cod] +*.sw[op] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +.eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 +__pycache__ + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.nox +.cache +.pytest_cache + + +# Mac +.DS_Store + +# JetBrains +.idea + +# VS Code +.vscode + +# emacs +*~ + +# Built documentation +docs/_build +bigquery/docs/generated +docs.metadata + +# Virtual environment +env/ + +# Test logs +coverage.xml +*sponge_log.xml + +# System test environment variables. +system_tests/local_test_setup + +# Make sure a generated file isn't accidentally committed. +pylintrc +pylintrc.test diff --git a/packages/google-apps-events-subscriptions/.repo-metadata.json b/packages/google-apps-events-subscriptions/.repo-metadata.json new file mode 100644 index 000000000000..f704766ed1fc --- /dev/null +++ b/packages/google-apps-events-subscriptions/.repo-metadata.json @@ -0,0 +1,17 @@ +{ + "name": "google-apps-events-subscriptions", + "name_pretty": "Google Workspace Events API", + "api_description": "The Google Workspace Events API lets you subscribe to events and manage change notifications across Google Workspace applications.", + "product_documentation": "https://developers.google.com/workspace/events", + "client_documentation": "https://googleapis.dev/python/google-apps-events-subscriptions/latest", + "issue_tracker": "https://github.com/googleapis/google-cloud-python/issues", + "release_level": "preview", + "language": "python", + "library_type": "GAPIC_AUTO", + "repo": "googleapis/google-cloud-python", + "distribution_name": "google-apps-events-subscriptions", + "api_id": "subscriptions.googleapis.com", + "default_version": "v1", + "codeowner_team": "", + "api_shortname": "subscriptions" +} diff --git a/packages/google-apps-events-subscriptions/CHANGELOG.md b/packages/google-apps-events-subscriptions/CHANGELOG.md new file mode 100644 index 000000000000..5ddad421e08f --- /dev/null +++ b/packages/google-apps-events-subscriptions/CHANGELOG.md @@ -0,0 +1 @@ +# Changelog \ No newline at end of file diff --git a/packages/google-apps-events-subscriptions/CODE_OF_CONDUCT.md b/packages/google-apps-events-subscriptions/CODE_OF_CONDUCT.md new file mode 100644 index 000000000000..039f43681204 --- /dev/null +++ b/packages/google-apps-events-subscriptions/CODE_OF_CONDUCT.md @@ -0,0 +1,95 @@ + +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +This Code of Conduct also applies outside the project spaces when the Project +Steward has a reasonable belief that an individual's behavior may have a +negative impact on the project or its community. + +## Conflict Resolution + +We do not believe that all conflict is bad; healthy debate and disagreement +often yield positive results. However, it is never okay to be disrespectful or +to engage in behavior that violates the project’s code of conduct. + +If you see someone violating the code of conduct, you are encouraged to address +the behavior directly with those involved. Many issues can be resolved quickly +and easily, and this gives people more control over the outcome of their +dispute. If you are unable to resolve the matter for any reason, or if the +behavior is threatening or harassing, report it. We are dedicated to providing +an environment where participants feel welcome and safe. + + +Reports should be directed to *googleapis-stewards@google.com*, the +Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to +receive and address reported violations of the code of conduct. They will then +work with a committee consisting of representatives from the Open Source +Programs Office and the Google Open Source Strategy team. If for any reason you +are uncomfortable reaching out to the Project Steward, please email +opensource@google.com. + +We will investigate every complaint, but you may not receive a direct response. +We will use our discretion in determining when and how to follow up on reported +incidents, which may range from not taking action to permanent expulsion from +the project and project-sponsored spaces. We will notify the accused of the +report and provide them an opportunity to discuss it before any action is taken. +The identity of the reporter will be omitted from the details of the report +supplied to the accused. In potentially harmful situations, such as ongoing +harassment or threats to anyone's safety, we may take action without notice. + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at +https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/packages/google-apps-events-subscriptions/CONTRIBUTING.rst b/packages/google-apps-events-subscriptions/CONTRIBUTING.rst new file mode 100644 index 000000000000..3e481e015da7 --- /dev/null +++ b/packages/google-apps-events-subscriptions/CONTRIBUTING.rst @@ -0,0 +1,271 @@ +.. Generated by synthtool. DO NOT EDIT! +############ +Contributing +############ + +#. **Please sign one of the contributor license agreements below.** +#. Fork the repo, develop and test your code changes, add docs. +#. Make sure that your commit messages clearly describe the changes. +#. Send a pull request. (Please Read: `Faster Pull Request Reviews`_) + +.. _Faster Pull Request Reviews: https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#best-practices-for-faster-reviews + +.. contents:: Here are some guidelines for hacking on the Google Cloud Client libraries. + +*************** +Adding Features +*************** + +In order to add a feature: + +- The feature must be documented in both the API and narrative + documentation. + +- The feature must work fully on the following CPython versions: + 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 on both UNIX and Windows. + +- The feature must not add unnecessary dependencies (where + "unnecessary" is of course subjective, but new dependencies should + be discussed). + +**************************** +Using a Development Checkout +**************************** + +You'll have to create a development environment using a Git checkout: + +- While logged into your GitHub account, navigate to the + ``google-cloud-python`` `repo`_ on GitHub. + +- Fork and clone the ``google-cloud-python`` repository to your GitHub account by + clicking the "Fork" button. + +- Clone your fork of ``google-cloud-python`` from your GitHub account to your local + computer, substituting your account username and specifying the destination + as ``hack-on-google-cloud-python``. E.g.:: + + $ cd ${HOME} + $ git clone git@github.com:USERNAME/google-cloud-python.git hack-on-google-cloud-python + $ cd hack-on-google-cloud-python + # Configure remotes such that you can pull changes from the googleapis/google-cloud-python + # repository into your local repository. + $ git remote add upstream git@github.com:googleapis/google-cloud-python.git + # fetch and merge changes from upstream into main + $ git fetch upstream + $ git merge upstream/main + +Now your local repo is set up such that you will push changes to your GitHub +repo, from which you can submit a pull request. + +To work on the codebase and run the tests, we recommend using ``nox``, +but you can also use a ``virtualenv`` of your own creation. + +.. _repo: https://github.com/googleapis/google-cloud-python + +Using ``nox`` +============= + +We use `nox `__ to instrument our tests. + +- To test your changes, run unit tests with ``nox``:: + $ nox -s unit + +- To run a single unit test:: + + $ nox -s unit-3.12 -- -k + + + .. note:: + + The unit tests and system tests are described in the + ``noxfile.py`` files in each directory. + +.. nox: https://pypi.org/project/nox/ + +***************************************** +I'm getting weird errors... Can you help? +***************************************** + +If the error mentions ``Python.h`` not being found, +install ``python-dev`` and try again. +On Debian/Ubuntu:: + + $ sudo apt-get install python-dev + +************ +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 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:: + + $ nox -s lint + +- In order to make ``nox -s lint`` run faster, you can set some environment + variables:: + + export GOOGLE_CLOUD_TESTING_REMOTE="upstream" + export GOOGLE_CLOUD_TESTING_BRANCH="main" + + By doing this, you are specifying the location of the most up-to-date + version of ``google-cloud-python``. The + remote name ``upstream`` should point to the official ``googleapis`` + checkout and the branch should be the default branch on that remote (``main``). + +- This repository contains configuration for the + `pre-commit `__ tool, which automates checking + our linters during a commit. If you have it installed on your ``$PATH``, + you can enable enforcing those checks via: + +.. code-block:: bash + + $ pre-commit install + pre-commit installed at .git/hooks/pre-commit + +Exceptions to PEP8: + +- Many unit tests use a helper method, ``_call_fut`` ("FUT" is short for + "Function-Under-Test"), which is PEP8-incompliant, but more readable. + Some also use a local variable, ``MUT`` (short for "Module-Under-Test"). + +******************** +Running System Tests +******************** + +- To run system tests, you can execute:: + + # Run all system tests + $ nox -s system + + # Run a single system test + $ nox -s system-3.12 -- -k + + + .. note:: + + System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11 and 3.12. + 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 + auth settings and change some configuration in your project to + run all the tests. + +- System tests will be run against an actual project. You should use local credentials from gcloud when possible. See `Best practices for application authentication `__. Some tests require a service account. For those tests see `Authenticating as a service account `__. + +************* +Test Coverage +************* + +- The codebase *must* have 100% test statement coverage after each commit. + You can test coverage via ``nox -s cover``. + +****************************************************** +Documentation Coverage and Building HTML Documentation +****************************************************** + +If you fix a bug, and the bug requires an API or behavior modification, all +documentation in this package which references that API or behavior must be +changed to reflect the bug fix, ideally in the same commit that fixes the bug +or adds the feature. + +Build the docs via: + + $ nox -s docs + +************************* +Samples and code snippets +************************* + +Code samples and snippets live in the `samples/` catalogue. Feel free to +provide more examples, but make sure to write tests for those examples. +Each folder containing example code requires its own `noxfile.py` script +which automates testing. If you decide to create a new folder, you can +base it on the `samples/snippets` folder (providing `noxfile.py` and +the requirements files). + +The tests will run against a real Google Cloud Project, so you should +configure them just like the System Tests. + +- To run sample tests, you can execute:: + + # Run all tests in a folder + $ cd samples/snippets + $ nox -s py-3.8 + + # Run a single sample test + $ cd samples/snippets + $ nox -s py-3.8 -- -k + +******************************************** +Note About ``README`` as it pertains to PyPI +******************************************** + +The `description on PyPI`_ for the project comes directly from the +``README``. Due to the reStructuredText (``rst``) parser used by +PyPI, relative links which will work on GitHub (e.g. ``CONTRIBUTING.rst`` +instead of +``https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst``) +may cause problems creating links or rendering the description. + +.. _description on PyPI: https://pypi.org/project/google-apps-events-subscriptions + + +************************* +Supported Python Versions +************************* + +We support: + +- `Python 3.7`_ +- `Python 3.8`_ +- `Python 3.9`_ +- `Python 3.10`_ +- `Python 3.11`_ +- `Python 3.12`_ + +.. _Python 3.7: https://docs.python.org/3.7/ +.. _Python 3.8: https://docs.python.org/3.8/ +.. _Python 3.9: https://docs.python.org/3.9/ +.. _Python 3.10: https://docs.python.org/3.10/ +.. _Python 3.11: https://docs.python.org/3.11/ +.. _Python 3.12: https://docs.python.org/3.12/ + + +Supported versions can be found in our ``noxfile.py`` `config`_. + +.. _config: https://github.com/googleapis/google-cloud-python/blob/main/packages/google-apps-events-subscriptions/noxfile.py + + +********** +Versioning +********** + +This library follows `Semantic Versioning`_. + +.. _Semantic Versioning: http://semver.org/ + +Some packages are currently in major version zero (``0.y.z``), which means that +anything may change at any time and the public API should not be considered +stable. + +****************************** +Contributor License Agreements +****************************** + +Before we can accept your pull requests you'll need to sign a Contributor +License Agreement (CLA): + +- **If you are an individual writing original source code** and **you own the + intellectual property**, then you'll need to sign an + `individual CLA `__. +- **If you work for a company that wants to allow you to contribute your work**, + then you'll need to sign a + `corporate CLA `__. + +You can sign these electronically (just scroll to the bottom). After that, +we'll be able to accept your pull requests. diff --git a/packages/google-apps-events-subscriptions/LICENSE b/packages/google-apps-events-subscriptions/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/packages/google-apps-events-subscriptions/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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/packages/google-apps-events-subscriptions/MANIFEST.in b/packages/google-apps-events-subscriptions/MANIFEST.in new file mode 100644 index 000000000000..e0a66705318e --- /dev/null +++ b/packages/google-apps-events-subscriptions/MANIFEST.in @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2023 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. + +# Generated by synthtool. DO NOT EDIT! +include README.rst LICENSE +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 diff --git a/packages/google-apps-events-subscriptions/README.rst b/packages/google-apps-events-subscriptions/README.rst new file mode 100644 index 000000000000..8a4284e93741 --- /dev/null +++ b/packages/google-apps-events-subscriptions/README.rst @@ -0,0 +1,108 @@ +Python Client for Google Workspace Events API +============================================= + +|preview| |pypi| |versions| + +`Google Workspace Events API`_: The Google Workspace Events API lets you subscribe to events and manage change notifications across Google Workspace applications. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-apps-events-subscriptions.svg + :target: https://pypi.org/project/google-apps-events-subscriptions/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-apps-events-subscriptions.svg + :target: https://pypi.org/project/google-apps-events-subscriptions/ +.. _Google Workspace Events API: https://developers.google.com/workspace/events +.. _Client Library Documentation: https://googleapis.dev/python/google-apps-events-subscriptions/latest +.. _Product Documentation: https://developers.google.com/workspace/events + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. `Enable the Google Workspace Events API.`_ +4. `Setup Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Enable the Google Workspace Events API.: https://developers.google.com/workspace/events +.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-events-subscriptions/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.7 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.6 + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-apps-events-subscriptions + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-apps-events-subscriptions + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Google Workspace Events API + to see other available methods on the client. +- Read the `Google Workspace Events API Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Google Workspace Events API Product documentation: https://developers.google.com/workspace/events +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst diff --git a/packages/google-apps-events-subscriptions/docs/CHANGELOG.md b/packages/google-apps-events-subscriptions/docs/CHANGELOG.md new file mode 120000 index 000000000000..04c99a55caae --- /dev/null +++ b/packages/google-apps-events-subscriptions/docs/CHANGELOG.md @@ -0,0 +1 @@ +../CHANGELOG.md \ No newline at end of file diff --git a/packages/google-apps-events-subscriptions/docs/README.rst b/packages/google-apps-events-subscriptions/docs/README.rst new file mode 120000 index 000000000000..89a0106941ff --- /dev/null +++ b/packages/google-apps-events-subscriptions/docs/README.rst @@ -0,0 +1 @@ +../README.rst \ No newline at end of file diff --git a/packages/google-apps-events-subscriptions/docs/_static/custom.css b/packages/google-apps-events-subscriptions/docs/_static/custom.css new file mode 100644 index 000000000000..b0a295464b23 --- /dev/null +++ b/packages/google-apps-events-subscriptions/docs/_static/custom.css @@ -0,0 +1,20 @@ +div#python2-eol { + border-color: red; + border-width: medium; +} + +/* Ensure minimum width for 'Parameters' / 'Returns' column */ +dl.field-list > dt { + min-width: 100px +} + +/* Insert space between methods for readability */ +dl.method { + padding-top: 10px; + padding-bottom: 10px +} + +/* Insert empty space between classes */ +dl.class { + padding-bottom: 50px +} diff --git a/packages/google-apps-events-subscriptions/docs/_templates/layout.html b/packages/google-apps-events-subscriptions/docs/_templates/layout.html new file mode 100644 index 000000000000..6316a537f72b --- /dev/null +++ b/packages/google-apps-events-subscriptions/docs/_templates/layout.html @@ -0,0 +1,50 @@ + +{% extends "!layout.html" %} +{%- block content %} +{%- if theme_fixed_sidebar|lower == 'true' %} +
+ {{ sidebar() }} + {%- block document %} +
+ {%- if render_sidebar %} +
+ {%- endif %} + + {%- block relbar_top %} + {%- if theme_show_relbar_top|tobool %} + + {%- endif %} + {% endblock %} + +
+
+ As of January 1, 2020 this library no longer supports Python 2 on the latest released version. + Library versions released prior to that date will continue to be available. For more information please + visit Python 2 support on Google Cloud. +
+ {% block body %} {% endblock %} +
+ + {%- block relbar_bottom %} + {%- if theme_show_relbar_bottom|tobool %} + + {%- endif %} + {% endblock %} + + {%- if render_sidebar %} +
+ {%- endif %} +
+ {%- endblock %} +
+
+{%- else %} +{{ super() }} +{%- endif %} +{%- endblock %} diff --git a/packages/google-apps-events-subscriptions/docs/conf.py b/packages/google-apps-events-subscriptions/docs/conf.py new file mode 100644 index 000000000000..48e7a2ad38cf --- /dev/null +++ b/packages/google-apps-events-subscriptions/docs/conf.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# google-apps-events-subscriptions documentation build configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import os +import shlex +import sys + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath("..")) + +# For plugins that can not read conf.py. +# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85 +sys.path.insert(0, os.path.abspath(".")) + +__version__ = "" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "1.5.5" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "sphinx.ext.coverage", + "sphinx.ext.doctest", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "recommonmark", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_options = {"members": True} +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = "google-apps-events-subscriptions" +copyright = "2019, Google" +author = "Google APIs" + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = __version__ +# The short X.Y version. +version = ".".join(release.split(".")[0:2]) + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [ + "_build", + "**/.nox/**/*", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/snippets/README.rst", +] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + "description": "Google Cloud Client Libraries for google-apps-events-subscriptions", + "github_user": "googleapis", + "github_repo": "google-cloud-python", + "github_banner": True, + "font_family": "'Roboto', Georgia, sans", + "head_font_family": "'Roboto', Georgia, serif", + "code_font_family": "'Roboto Mono', 'Consolas', monospace", +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = "google-apps-events-subscriptions-doc" + +# -- Options for warnings ------------------------------------------------------ + + +suppress_warnings = [ + # Temporarily suppress this to avoid "more than one target found for + # cross-reference" warning, which are intractable for us to avoid while in + # a mono-repo. + # See https://github.com/sphinx-doc/sphinx/blob + # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 + "ref.python" +] + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Latex figure (float) alignment + #'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + root_doc, + "google-apps-events-subscriptions.tex", + "google-apps-events-subscriptions Documentation", + author, + "manual", + ) +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + root_doc, + "google-apps-events-subscriptions", + "google-apps-events-subscriptions Documentation", + [author], + 1, + ) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + root_doc, + "google-apps-events-subscriptions", + "google-apps-events-subscriptions Documentation", + author, + "google-apps-events-subscriptions", + "google-apps-events-subscriptions Library", + "APIs", + ) +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("https://python.readthedocs.org/en/latest/", None), + "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), + "google.api_core": ( + "https://googleapis.dev/python/google-api-core/latest/", + None, + ), + "grpc": ("https://grpc.github.io/grpc/python/", None), + "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# Napoleon settings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True diff --git a/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/services_.rst b/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/services_.rst new file mode 100644 index 000000000000..8c1977ce4c50 --- /dev/null +++ b/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/services_.rst @@ -0,0 +1,6 @@ +Services for Google Apps Events Subscriptions v1 API +==================================================== +.. toctree:: + :maxdepth: 2 + + subscriptions_service diff --git a/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/subscriptions_service.rst b/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/subscriptions_service.rst new file mode 100644 index 000000000000..66cad075bb1a --- /dev/null +++ b/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/subscriptions_service.rst @@ -0,0 +1,10 @@ +SubscriptionsService +-------------------------------------- + +.. automodule:: google.apps.events_subscriptions_v1.services.subscriptions_service + :members: + :inherited-members: + +.. automodule:: google.apps.events_subscriptions_v1.services.subscriptions_service.pagers + :members: + :inherited-members: diff --git a/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/types_.rst b/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/types_.rst new file mode 100644 index 000000000000..c7c5912e59a6 --- /dev/null +++ b/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/types_.rst @@ -0,0 +1,6 @@ +Types for Google Apps Events Subscriptions v1 API +================================================= + +.. automodule:: google.apps.events_subscriptions_v1.types + :members: + :show-inheritance: diff --git a/packages/google-apps-events-subscriptions/docs/index.rst b/packages/google-apps-events-subscriptions/docs/index.rst new file mode 100644 index 000000000000..f07b4fce6385 --- /dev/null +++ b/packages/google-apps-events-subscriptions/docs/index.rst @@ -0,0 +1,23 @@ +.. include:: README.rst + +.. include:: multiprocessing.rst + + +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + events_subscriptions_v1/services_ + events_subscriptions_v1/types_ + + +Changelog +--------- + +For a list of all ``google-apps-events-subscriptions`` releases: + +.. toctree:: + :maxdepth: 2 + + CHANGELOG diff --git a/packages/google-apps-events-subscriptions/docs/multiprocessing.rst b/packages/google-apps-events-subscriptions/docs/multiprocessing.rst new file mode 100644 index 000000000000..536d17b2ea65 --- /dev/null +++ b/packages/google-apps-events-subscriptions/docs/multiprocessing.rst @@ -0,0 +1,7 @@ +.. note:: + + Because this client uses :mod:`grpc` library, it is safe to + share instances across threads. In multiprocessing scenarios, the best + practice is to create client instances *after* the invocation of + :func:`os.fork` by :class:`multiprocessing.pool.Pool` or + :class:`multiprocessing.Process`. diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/__init__.py new file mode 100644 index 000000000000..852246f347b9 --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/__init__.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from google.apps.events_subscriptions import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.apps.events_subscriptions_v1.services.subscriptions_service.async_client import ( + SubscriptionsServiceAsyncClient, +) +from google.apps.events_subscriptions_v1.services.subscriptions_service.client import ( + SubscriptionsServiceClient, +) +from google.apps.events_subscriptions_v1.types.subscription_resource import ( + NotificationEndpoint, + PayloadOptions, + Subscription, +) +from google.apps.events_subscriptions_v1.types.subscriptions_service import ( + CreateSubscriptionMetadata, + CreateSubscriptionRequest, + DeleteSubscriptionMetadata, + DeleteSubscriptionRequest, + GetSubscriptionRequest, + ListSubscriptionsRequest, + ListSubscriptionsResponse, + ReactivateSubscriptionMetadata, + ReactivateSubscriptionRequest, + UpdateSubscriptionMetadata, + UpdateSubscriptionRequest, +) + +__all__ = ( + "SubscriptionsServiceClient", + "SubscriptionsServiceAsyncClient", + "NotificationEndpoint", + "PayloadOptions", + "Subscription", + "CreateSubscriptionMetadata", + "CreateSubscriptionRequest", + "DeleteSubscriptionMetadata", + "DeleteSubscriptionRequest", + "GetSubscriptionRequest", + "ListSubscriptionsRequest", + "ListSubscriptionsResponse", + "ReactivateSubscriptionMetadata", + "ReactivateSubscriptionRequest", + "UpdateSubscriptionMetadata", + "UpdateSubscriptionRequest", +) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/gapic_version.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/gapic_version.py new file mode 100644 index 000000000000..360a0d13ebdd --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/py.typed b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/py.typed new file mode 100644 index 000000000000..c814fdfb4bba --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-apps-events-subscriptions package uses inline types. diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py new file mode 100644 index 000000000000..e03a1415f0a6 --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from google.apps.events_subscriptions_v1 import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.subscriptions_service import ( + SubscriptionsServiceAsyncClient, + SubscriptionsServiceClient, +) +from .types.subscription_resource import ( + NotificationEndpoint, + PayloadOptions, + Subscription, +) +from .types.subscriptions_service import ( + CreateSubscriptionMetadata, + CreateSubscriptionRequest, + DeleteSubscriptionMetadata, + DeleteSubscriptionRequest, + GetSubscriptionRequest, + ListSubscriptionsRequest, + ListSubscriptionsResponse, + ReactivateSubscriptionMetadata, + ReactivateSubscriptionRequest, + UpdateSubscriptionMetadata, + UpdateSubscriptionRequest, +) + +__all__ = ( + "SubscriptionsServiceAsyncClient", + "CreateSubscriptionMetadata", + "CreateSubscriptionRequest", + "DeleteSubscriptionMetadata", + "DeleteSubscriptionRequest", + "GetSubscriptionRequest", + "ListSubscriptionsRequest", + "ListSubscriptionsResponse", + "NotificationEndpoint", + "PayloadOptions", + "ReactivateSubscriptionMetadata", + "ReactivateSubscriptionRequest", + "Subscription", + "SubscriptionsServiceClient", + "UpdateSubscriptionMetadata", + "UpdateSubscriptionRequest", +) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_metadata.json b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_metadata.json new file mode 100644 index 000000000000..f90006e089ce --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_metadata.json @@ -0,0 +1,118 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.apps.events_subscriptions_v1", + "protoPackage": "google.apps.events.subscriptions.v1", + "schema": "1.0", + "services": { + "SubscriptionsService": { + "clients": { + "grpc": { + "libraryClient": "SubscriptionsServiceClient", + "rpcs": { + "CreateSubscription": { + "methods": [ + "create_subscription" + ] + }, + "DeleteSubscription": { + "methods": [ + "delete_subscription" + ] + }, + "GetSubscription": { + "methods": [ + "get_subscription" + ] + }, + "ListSubscriptions": { + "methods": [ + "list_subscriptions" + ] + }, + "ReactivateSubscription": { + "methods": [ + "reactivate_subscription" + ] + }, + "UpdateSubscription": { + "methods": [ + "update_subscription" + ] + } + } + }, + "grpc-async": { + "libraryClient": "SubscriptionsServiceAsyncClient", + "rpcs": { + "CreateSubscription": { + "methods": [ + "create_subscription" + ] + }, + "DeleteSubscription": { + "methods": [ + "delete_subscription" + ] + }, + "GetSubscription": { + "methods": [ + "get_subscription" + ] + }, + "ListSubscriptions": { + "methods": [ + "list_subscriptions" + ] + }, + "ReactivateSubscription": { + "methods": [ + "reactivate_subscription" + ] + }, + "UpdateSubscription": { + "methods": [ + "update_subscription" + ] + } + } + }, + "rest": { + "libraryClient": "SubscriptionsServiceClient", + "rpcs": { + "CreateSubscription": { + "methods": [ + "create_subscription" + ] + }, + "DeleteSubscription": { + "methods": [ + "delete_subscription" + ] + }, + "GetSubscription": { + "methods": [ + "get_subscription" + ] + }, + "ListSubscriptions": { + "methods": [ + "list_subscriptions" + ] + }, + "ReactivateSubscription": { + "methods": [ + "reactivate_subscription" + ] + }, + "UpdateSubscription": { + "methods": [ + "update_subscription" + ] + } + } + } + } + } + } +} diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_version.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_version.py new file mode 100644 index 000000000000..360a0d13ebdd --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/py.typed b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/py.typed new file mode 100644 index 000000000000..c814fdfb4bba --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-apps-events-subscriptions package uses inline types. diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/__init__.py new file mode 100644 index 000000000000..c72dd2737d41 --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from .async_client import SubscriptionsServiceAsyncClient +from .client import SubscriptionsServiceClient + +__all__ = ( + "SubscriptionsServiceClient", + "SubscriptionsServiceAsyncClient", +) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/async_client.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/async_client.py new file mode 100644 index 000000000000..06b847e94cad --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/async_client.py @@ -0,0 +1,1189 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from collections import OrderedDict +import functools +import re +from typing import ( + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.apps.events_subscriptions_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.apps.events_subscriptions_v1.services.subscriptions_service import pagers +from google.apps.events_subscriptions_v1.types import ( + subscription_resource, + subscriptions_service, +) + +from .client import SubscriptionsServiceClient +from .transports.base import DEFAULT_CLIENT_INFO, SubscriptionsServiceTransport +from .transports.grpc_asyncio import SubscriptionsServiceGrpcAsyncIOTransport + + +class SubscriptionsServiceAsyncClient: + """A service that manages subscriptions to Google Workspace + events. + """ + + _client: SubscriptionsServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = SubscriptionsServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = SubscriptionsServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = SubscriptionsServiceClient._DEFAULT_UNIVERSE + + subscription_path = staticmethod(SubscriptionsServiceClient.subscription_path) + parse_subscription_path = staticmethod( + SubscriptionsServiceClient.parse_subscription_path + ) + topic_path = staticmethod(SubscriptionsServiceClient.topic_path) + parse_topic_path = staticmethod(SubscriptionsServiceClient.parse_topic_path) + user_path = staticmethod(SubscriptionsServiceClient.user_path) + parse_user_path = staticmethod(SubscriptionsServiceClient.parse_user_path) + common_billing_account_path = staticmethod( + SubscriptionsServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + SubscriptionsServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(SubscriptionsServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + SubscriptionsServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + SubscriptionsServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + SubscriptionsServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(SubscriptionsServiceClient.common_project_path) + parse_common_project_path = staticmethod( + SubscriptionsServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(SubscriptionsServiceClient.common_location_path) + parse_common_location_path = staticmethod( + SubscriptionsServiceClient.parse_common_location_path + ) + + @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: + SubscriptionsServiceAsyncClient: The constructed client. + """ + return SubscriptionsServiceClient.from_service_account_info.__func__(SubscriptionsServiceAsyncClient, 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: + SubscriptionsServiceAsyncClient: The constructed client. + """ + return SubscriptionsServiceClient.from_service_account_file.__func__(SubscriptionsServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return SubscriptionsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> SubscriptionsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SubscriptionsServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = functools.partial( + type(SubscriptionsServiceClient).get_transport_class, + type(SubscriptionsServiceClient), + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, SubscriptionsServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the subscriptions service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + 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, ~.SubscriptionsServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = SubscriptionsServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def create_subscription( + self, + request: Optional[ + Union[subscriptions_service.CreateSubscriptionRequest, dict] + ] = None, + *, + subscription: Optional[subscription_resource.Subscription] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a Google Workspace subscription. To learn how to use + this method, see `Create a Google Workspace + subscription `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + async def sample_create_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + subscription = events_subscriptions_v1.Subscription() + subscription.target_resource = "target_resource_value" + subscription.event_types = ['event_types_value1', 'event_types_value2'] + subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" + + request = events_subscriptions_v1.CreateSubscriptionRequest( + subscription=subscription, + ) + + # Make the request + operation = client.create_subscription(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.apps.events_subscriptions_v1.types.CreateSubscriptionRequest, dict]]): + The request object. The request message for + [SubscriptionsService.CreateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription]. + subscription (:class:`google.apps.events_subscriptions_v1.types.Subscription`): + Required. The subscription resource + to create. + + This corresponds to the ``subscription`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn + more about subscriptions, see the [Google Workspace + Events API + overview](\ https://developers.google.com/workspace/events/guides). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([subscription]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = subscriptions_service.CreateSubscriptionRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if subscription is not None: + request.subscription = subscription + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_subscription, + default_timeout=60.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + subscription_resource.Subscription, + metadata_type=subscriptions_service.CreateSubscriptionMetadata, + ) + + # Done; return the response. + return response + + async def delete_subscription( + self, + request: Optional[ + Union[subscriptions_service.DeleteSubscriptionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a Google Workspace subscription. To learn how to use + this method, see `Delete a Google Workspace + subscription `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + async def sample_delete_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.DeleteSubscriptionRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_subscription(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.apps.events_subscriptions_v1.types.DeleteSubscriptionRequest, dict]]): + The request object. The request message for + [SubscriptionsService.DeleteSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription]. + name (:class:`str`): + Required. Resource name of the subscription to delete. + + Format: ``subscriptions/{subscription}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = subscriptions_service.DeleteSubscriptionRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_subscription, + default_timeout=60.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=subscriptions_service.DeleteSubscriptionMetadata, + ) + + # Done; return the response. + return response + + async def get_subscription( + self, + request: Optional[ + Union[subscriptions_service.GetSubscriptionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> subscription_resource.Subscription: + r"""Gets details about a Google Workspace subscription. To learn how + to use this method, see `Get details about a Google Workspace + subscription `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + async def sample_get_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.GetSubscriptionRequest( + name="name_value", + ) + + # Make the request + response = await client.get_subscription(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.apps.events_subscriptions_v1.types.GetSubscriptionRequest, dict]]): + The request object. The request message for + [SubscriptionsService.GetSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription]. + name (:class:`str`): + Required. Resource name of the subscription. + + Format: ``subscriptions/{subscription}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.apps.events_subscriptions_v1.types.Subscription: + A subscription to receive events about a Google Workspace resource. To learn + more about subscriptions, see the [Google Workspace + Events API + overview](\ https://developers.google.com/workspace/events/guides). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = subscriptions_service.GetSubscriptionRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_subscription, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_subscriptions( + self, + request: Optional[ + Union[subscriptions_service.ListSubscriptionsRequest, dict] + ] = None, + *, + page_size: Optional[int] = None, + page_token: Optional[str] = None, + filter: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListSubscriptionsAsyncPager: + r"""Lists Google Workspace subscriptions. To learn how to use this + method, see `List Google Workspace + subscriptions `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + async def sample_list_subscriptions(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.ListSubscriptionsRequest( + filter="filter_value", + ) + + # Make the request + page_result = client.list_subscriptions(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest, dict]]): + The request object. The request message for + [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. + page_size (:class:`int`): + Optional. The maximum number of subscriptions to return. + The service might return fewer than this value. + + If unspecified or set to ``0``, up to 50 subscriptions + are returned. + + The maximum value is 100. If you specify a value more + than 100, the system only returns 100 subscriptions. + + This corresponds to the ``page_size`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + page_token (:class:`str`): + Optional. A page token, received from + a previous list subscriptions call. + Provide this parameter to retrieve the + subsequent page. + + When paginating, the filter value should + match the call that provided the page + token. Passing a different value might + lead to unexpected results. + + This corresponds to the ``page_token`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + filter (:class:`str`): + Required. A query filter. + + You can filter subscriptions by event type + (``event_types``) and target resource + (``target_resource``). + + You must specify at least one event type in your query. + To filter for multiple event types, use the ``OR`` + operator. + + To filter by both event type and target resource, use + the ``AND`` operator and specify the full resource name, + such as ``//chat.googleapis.com/spaces/{space}``. + + For example, the following queries are valid: + + :: + + event_types:"google.workspace.chat.membership.v1.updated" OR + event_types:"google.workspace.chat.message.v1.created" + + event_types:"google.workspace.chat.message.v1.created" AND + target_resource="//chat.googleapis.com/spaces/{space}" + + ( event_types:"google.workspace.chat.membership.v1.updated" OR + event_types:"google.workspace.chat.message.v1.created" ) AND + target_resource="//chat.googleapis.com/spaces/{space}" + + The server rejects invalid queries with an + ``INVALID_ARGUMENT`` error. + + This corresponds to the ``filter`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.apps.events_subscriptions_v1.services.subscriptions_service.pagers.ListSubscriptionsAsyncPager: + The response message for + [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([page_size, page_token, filter]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = subscriptions_service.ListSubscriptionsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if page_size is not None: + request.page_size = page_size + if page_token is not None: + request.page_token = page_token + if filter is not None: + request.filter = filter + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_subscriptions, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListSubscriptionsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_subscription( + self, + request: Optional[ + Union[subscriptions_service.UpdateSubscriptionRequest, dict] + ] = None, + *, + subscription: Optional[subscription_resource.Subscription] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates or renews a Google Workspace subscription. To learn how + to use this method, see `Update or renew a Google Workspace + subscription `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + async def sample_update_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + subscription = events_subscriptions_v1.Subscription() + subscription.target_resource = "target_resource_value" + subscription.event_types = ['event_types_value1', 'event_types_value2'] + subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" + + request = events_subscriptions_v1.UpdateSubscriptionRequest( + subscription=subscription, + ) + + # Make the request + operation = client.update_subscription(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.apps.events_subscriptions_v1.types.UpdateSubscriptionRequest, dict]]): + The request object. The request message for + [SubscriptionsService.UpdateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription]. + subscription (:class:`google.apps.events_subscriptions_v1.types.Subscription`): + Required. The subscription to update. + + The subscription's ``name`` field is used to identify + the subscription to update. + + This corresponds to the ``subscription`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. Required. The field to update. + + You can update one of the following fields in a + subscription: + + - [``expire_time``][google.apps.events.subscriptions.v1.Subscription.expire_time]: + The timestamp when the subscription expires. + - [``ttl``][google.apps.events.subscriptions.v1.Subscription.ttl]: + The time-to-live (TTL) or duration of the + subscription. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn + more about subscriptions, see the [Google Workspace + Events API + overview](\ https://developers.google.com/workspace/events/guides). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([subscription, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = subscriptions_service.UpdateSubscriptionRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if subscription is not None: + request.subscription = subscription + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_subscription, + default_timeout=60.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("subscription.name", request.subscription.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + subscription_resource.Subscription, + metadata_type=subscriptions_service.UpdateSubscriptionMetadata, + ) + + # Done; return the response. + return response + + async def reactivate_subscription( + self, + request: Optional[ + Union[subscriptions_service.ReactivateSubscriptionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Reactivates a suspended Google Workspace subscription. + + This method resets your subscription's ``State`` field to + ``ACTIVE``. Before you use this method, you must fix the error + that suspended the subscription. To learn how to use this + method, see `Reactivate a Google Workspace + subscription `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + async def sample_reactivate_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.ReactivateSubscriptionRequest( + name="name_value", + ) + + # Make the request + operation = client.reactivate_subscription(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.apps.events_subscriptions_v1.types.ReactivateSubscriptionRequest, dict]]): + The request object. The request message for + [SubscriptionsService.ReactivateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription]. + name (:class:`str`): + Required. Resource name of the subscription. + + Format: ``subscriptions/{subscription}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn + more about subscriptions, see the [Google Workspace + Events API + overview](\ https://developers.google.com/workspace/events/guides). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = subscriptions_service.ReactivateSubscriptionRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.reactivate_subscription, + default_timeout=60.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + subscription_resource.Subscription, + metadata_type=subscriptions_service.ReactivateSubscriptionMetadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # 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): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "SubscriptionsServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +__all__ = ("SubscriptionsServiceAsyncClient",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/client.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/client.py new file mode 100644 index 000000000000..4e4038f8a8f0 --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/client.py @@ -0,0 +1,1609 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from collections import OrderedDict +import os +import re +from typing import ( + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.apps.events_subscriptions_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.apps.events_subscriptions_v1.services.subscriptions_service import pagers +from google.apps.events_subscriptions_v1.types import ( + subscription_resource, + subscriptions_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, SubscriptionsServiceTransport +from .transports.grpc import SubscriptionsServiceGrpcTransport +from .transports.grpc_asyncio import SubscriptionsServiceGrpcAsyncIOTransport +from .transports.rest import SubscriptionsServiceRestTransport + + +class SubscriptionsServiceClientMeta(type): + """Metaclass for the SubscriptionsService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[SubscriptionsServiceTransport]] + _transport_registry["grpc"] = SubscriptionsServiceGrpcTransport + _transport_registry["grpc_asyncio"] = SubscriptionsServiceGrpcAsyncIOTransport + _transport_registry["rest"] = SubscriptionsServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[SubscriptionsServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class SubscriptionsServiceClient(metaclass=SubscriptionsServiceClientMeta): + """A service that manages subscriptions to Google Workspace + events. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "workspaceevents.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "workspaceevents.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @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: + SubscriptionsServiceClient: 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 + 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: + SubscriptionsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SubscriptionsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SubscriptionsServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def subscription_path( + subscription: str, + ) -> str: + """Returns a fully-qualified subscription string.""" + return "subscriptions/{subscription}".format( + subscription=subscription, + ) + + @staticmethod + def parse_subscription_path(path: str) -> Dict[str, str]: + """Parses a subscription path into its component segments.""" + m = re.match(r"^subscriptions/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def topic_path( + project: str, + topic: str, + ) -> str: + """Returns a fully-qualified topic string.""" + return "projects/{project}/topics/{topic}".format( + project=project, + topic=topic, + ) + + @staticmethod + def parse_topic_path(path: str) -> Dict[str, str]: + """Parses a topic path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/topics/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def user_path( + user: str, + ) -> str: + """Returns a fully-qualified user string.""" + return "users/{user}".format( + user=user, + ) + + @staticmethod + def parse_user_path(path: str) -> Dict[str, str]: + """Parses a user path into its component segments.""" + m = re.match(r"^users/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = SubscriptionsServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = SubscriptionsServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = SubscriptionsServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + @staticmethod + def _compare_universes( + client_universe: str, credentials: ga_credentials.Credentials + ) -> bool: + """Returns True iff the universe domains used by the client and credentials match. + + Args: + client_universe (str): The universe domain configured via the client options. + credentials (ga_credentials.Credentials): The credentials being used in the client. + + Returns: + bool: True iff client_universe matches the universe in credentials. + + Raises: + ValueError: when client_universe does not match the universe in credentials. + """ + + default_universe = SubscriptionsServiceClient._DEFAULT_UNIVERSE + credentials_universe = getattr(credentials, "universe_domain", default_universe) + + if client_universe != credentials_universe: + raise ValueError( + "The configured universe domain " + f"({client_universe}) does not match the universe domain " + f"found in the credentials ({credentials_universe}). " + "If you haven't configured the universe domain explicitly, " + f"`{default_universe}` is the default." + ) + return True + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + self._is_universe_domain_valid = ( + self._is_universe_domain_valid + or SubscriptionsServiceClient._compare_universes( + self.universe_domain, self.transport._credentials + ) + ) + return self._is_universe_domain_valid + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, SubscriptionsServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the subscriptions service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + 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, SubscriptionsServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = SubscriptionsServiceClient._read_environment_variables() + self._client_cert_source = SubscriptionsServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = SubscriptionsServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + api_key_value = getattr(self._client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, SubscriptionsServiceTransport) + if transport_provided: + # transport is a SubscriptionsServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(SubscriptionsServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or SubscriptionsServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + Transport = type(self).get_transport_class(cast(str, transport)) + self._transport = Transport( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + def create_subscription( + self, + request: Optional[ + Union[subscriptions_service.CreateSubscriptionRequest, dict] + ] = None, + *, + subscription: Optional[subscription_resource.Subscription] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Creates a Google Workspace subscription. To learn how to use + this method, see `Create a Google Workspace + subscription `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + def sample_create_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + subscription = events_subscriptions_v1.Subscription() + subscription.target_resource = "target_resource_value" + subscription.event_types = ['event_types_value1', 'event_types_value2'] + subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" + + request = events_subscriptions_v1.CreateSubscriptionRequest( + subscription=subscription, + ) + + # Make the request + operation = client.create_subscription(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.apps.events_subscriptions_v1.types.CreateSubscriptionRequest, dict]): + The request object. The request message for + [SubscriptionsService.CreateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription]. + subscription (google.apps.events_subscriptions_v1.types.Subscription): + Required. The subscription resource + to create. + + This corresponds to the ``subscription`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn + more about subscriptions, see the [Google Workspace + Events API + overview](\ https://developers.google.com/workspace/events/guides). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([subscription]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a subscriptions_service.CreateSubscriptionRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, subscriptions_service.CreateSubscriptionRequest): + request = subscriptions_service.CreateSubscriptionRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if subscription is not None: + request.subscription = subscription + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_subscription] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + subscription_resource.Subscription, + metadata_type=subscriptions_service.CreateSubscriptionMetadata, + ) + + # Done; return the response. + return response + + def delete_subscription( + self, + request: Optional[ + Union[subscriptions_service.DeleteSubscriptionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Deletes a Google Workspace subscription. To learn how to use + this method, see `Delete a Google Workspace + subscription `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + def sample_delete_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.DeleteSubscriptionRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_subscription(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.apps.events_subscriptions_v1.types.DeleteSubscriptionRequest, dict]): + The request object. The request message for + [SubscriptionsService.DeleteSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription]. + name (str): + Required. Resource name of the subscription to delete. + + Format: ``subscriptions/{subscription}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a subscriptions_service.DeleteSubscriptionRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, subscriptions_service.DeleteSubscriptionRequest): + request = subscriptions_service.DeleteSubscriptionRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_subscription] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=subscriptions_service.DeleteSubscriptionMetadata, + ) + + # Done; return the response. + return response + + def get_subscription( + self, + request: Optional[ + Union[subscriptions_service.GetSubscriptionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> subscription_resource.Subscription: + r"""Gets details about a Google Workspace subscription. To learn how + to use this method, see `Get details about a Google Workspace + subscription `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + def sample_get_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.GetSubscriptionRequest( + name="name_value", + ) + + # Make the request + response = client.get_subscription(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.apps.events_subscriptions_v1.types.GetSubscriptionRequest, dict]): + The request object. The request message for + [SubscriptionsService.GetSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription]. + name (str): + Required. Resource name of the subscription. + + Format: ``subscriptions/{subscription}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.apps.events_subscriptions_v1.types.Subscription: + A subscription to receive events about a Google Workspace resource. To learn + more about subscriptions, see the [Google Workspace + Events API + overview](\ https://developers.google.com/workspace/events/guides). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a subscriptions_service.GetSubscriptionRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, subscriptions_service.GetSubscriptionRequest): + request = subscriptions_service.GetSubscriptionRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_subscription] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_subscriptions( + self, + request: Optional[ + Union[subscriptions_service.ListSubscriptionsRequest, dict] + ] = None, + *, + page_size: Optional[int] = None, + page_token: Optional[str] = None, + filter: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListSubscriptionsPager: + r"""Lists Google Workspace subscriptions. To learn how to use this + method, see `List Google Workspace + subscriptions `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + def sample_list_subscriptions(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.ListSubscriptionsRequest( + filter="filter_value", + ) + + # Make the request + page_result = client.list_subscriptions(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest, dict]): + The request object. The request message for + [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. + page_size (int): + Optional. The maximum number of subscriptions to return. + The service might return fewer than this value. + + If unspecified or set to ``0``, up to 50 subscriptions + are returned. + + The maximum value is 100. If you specify a value more + than 100, the system only returns 100 subscriptions. + + This corresponds to the ``page_size`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + page_token (str): + Optional. A page token, received from + a previous list subscriptions call. + Provide this parameter to retrieve the + subsequent page. + + When paginating, the filter value should + match the call that provided the page + token. Passing a different value might + lead to unexpected results. + + This corresponds to the ``page_token`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + filter (str): + Required. A query filter. + + You can filter subscriptions by event type + (``event_types``) and target resource + (``target_resource``). + + You must specify at least one event type in your query. + To filter for multiple event types, use the ``OR`` + operator. + + To filter by both event type and target resource, use + the ``AND`` operator and specify the full resource name, + such as ``//chat.googleapis.com/spaces/{space}``. + + For example, the following queries are valid: + + :: + + event_types:"google.workspace.chat.membership.v1.updated" OR + event_types:"google.workspace.chat.message.v1.created" + + event_types:"google.workspace.chat.message.v1.created" AND + target_resource="//chat.googleapis.com/spaces/{space}" + + ( event_types:"google.workspace.chat.membership.v1.updated" OR + event_types:"google.workspace.chat.message.v1.created" ) AND + target_resource="//chat.googleapis.com/spaces/{space}" + + The server rejects invalid queries with an + ``INVALID_ARGUMENT`` error. + + This corresponds to the ``filter`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.apps.events_subscriptions_v1.services.subscriptions_service.pagers.ListSubscriptionsPager: + The response message for + [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([page_size, page_token, filter]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a subscriptions_service.ListSubscriptionsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, subscriptions_service.ListSubscriptionsRequest): + request = subscriptions_service.ListSubscriptionsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if page_size is not None: + request.page_size = page_size + if page_token is not None: + request.page_token = page_token + if filter is not None: + request.filter = filter + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_subscriptions] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListSubscriptionsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_subscription( + self, + request: Optional[ + Union[subscriptions_service.UpdateSubscriptionRequest, dict] + ] = None, + *, + subscription: Optional[subscription_resource.Subscription] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Updates or renews a Google Workspace subscription. To learn how + to use this method, see `Update or renew a Google Workspace + subscription `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + def sample_update_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + subscription = events_subscriptions_v1.Subscription() + subscription.target_resource = "target_resource_value" + subscription.event_types = ['event_types_value1', 'event_types_value2'] + subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" + + request = events_subscriptions_v1.UpdateSubscriptionRequest( + subscription=subscription, + ) + + # Make the request + operation = client.update_subscription(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.apps.events_subscriptions_v1.types.UpdateSubscriptionRequest, dict]): + The request object. The request message for + [SubscriptionsService.UpdateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription]. + subscription (google.apps.events_subscriptions_v1.types.Subscription): + Required. The subscription to update. + + The subscription's ``name`` field is used to identify + the subscription to update. + + This corresponds to the ``subscription`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Required. The field to update. + + You can update one of the following fields in a + subscription: + + - [``expire_time``][google.apps.events.subscriptions.v1.Subscription.expire_time]: + The timestamp when the subscription expires. + - [``ttl``][google.apps.events.subscriptions.v1.Subscription.ttl]: + The time-to-live (TTL) or duration of the + subscription. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn + more about subscriptions, see the [Google Workspace + Events API + overview](\ https://developers.google.com/workspace/events/guides). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([subscription, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a subscriptions_service.UpdateSubscriptionRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, subscriptions_service.UpdateSubscriptionRequest): + request = subscriptions_service.UpdateSubscriptionRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if subscription is not None: + request.subscription = subscription + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_subscription] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("subscription.name", request.subscription.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + subscription_resource.Subscription, + metadata_type=subscriptions_service.UpdateSubscriptionMetadata, + ) + + # Done; return the response. + return response + + def reactivate_subscription( + self, + request: Optional[ + Union[subscriptions_service.ReactivateSubscriptionRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Reactivates a suspended Google Workspace subscription. + + This method resets your subscription's ``State`` field to + ``ACTIVE``. Before you use this method, you must fix the error + that suspended the subscription. To learn how to use this + method, see `Reactivate a Google Workspace + subscription `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.apps import events_subscriptions_v1 + + def sample_reactivate_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.ReactivateSubscriptionRequest( + name="name_value", + ) + + # Make the request + operation = client.reactivate_subscription(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.apps.events_subscriptions_v1.types.ReactivateSubscriptionRequest, dict]): + The request object. The request message for + [SubscriptionsService.ReactivateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription]. + name (str): + Required. Resource name of the subscription. + + Format: ``subscriptions/{subscription}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn + more about subscriptions, see the [Google Workspace + Events API + overview](\ https://developers.google.com/workspace/events/guides). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a subscriptions_service.ReactivateSubscriptionRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, subscriptions_service.ReactivateSubscriptionRequest): + request = subscriptions_service.ReactivateSubscriptionRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.reactivate_subscription] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + subscription_resource.Subscription, + metadata_type=subscriptions_service.ReactivateSubscriptionMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "SubscriptionsServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # 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): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +__all__ = ("SubscriptionsServiceClient",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/pagers.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/pagers.py new file mode 100644 index 000000000000..8832aa78df23 --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/pagers.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, +) + +from google.apps.events_subscriptions_v1.types import ( + subscription_resource, + subscriptions_service, +) + + +class ListSubscriptionsPager: + """A pager for iterating through ``list_subscriptions`` requests. + + This class thinly wraps an initial + :class:`google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``subscriptions`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListSubscriptions`` requests and continue to iterate + through the ``subscriptions`` field on the + corresponding responses. + + All the usual :class:`google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., subscriptions_service.ListSubscriptionsResponse], + request: subscriptions_service.ListSubscriptionsRequest, + response: subscriptions_service.ListSubscriptionsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest): + The initial request object. + response (google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = subscriptions_service.ListSubscriptionsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[subscriptions_service.ListSubscriptionsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[subscription_resource.Subscription]: + for page in self.pages: + yield from page.subscriptions + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListSubscriptionsAsyncPager: + """A pager for iterating through ``list_subscriptions`` requests. + + This class thinly wraps an initial + :class:`google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``subscriptions`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListSubscriptions`` requests and continue to iterate + through the ``subscriptions`` field on the + corresponding responses. + + All the usual :class:`google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[subscriptions_service.ListSubscriptionsResponse] + ], + request: subscriptions_service.ListSubscriptionsRequest, + response: subscriptions_service.ListSubscriptionsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest): + The initial request object. + response (google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = subscriptions_service.ListSubscriptionsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[subscriptions_service.ListSubscriptionsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[subscription_resource.Subscription]: + async def async_generator(): + async for page in self.pages: + for response in page.subscriptions: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/__init__.py new file mode 100644 index 000000000000..ad7767d7f900 --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import SubscriptionsServiceTransport +from .grpc import SubscriptionsServiceGrpcTransport +from .grpc_asyncio import SubscriptionsServiceGrpcAsyncIOTransport +from .rest import SubscriptionsServiceRestInterceptor, SubscriptionsServiceRestTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[SubscriptionsServiceTransport]] +_transport_registry["grpc"] = SubscriptionsServiceGrpcTransport +_transport_registry["grpc_asyncio"] = SubscriptionsServiceGrpcAsyncIOTransport +_transport_registry["rest"] = SubscriptionsServiceRestTransport + +__all__ = ( + "SubscriptionsServiceTransport", + "SubscriptionsServiceGrpcTransport", + "SubscriptionsServiceGrpcAsyncIOTransport", + "SubscriptionsServiceRestTransport", + "SubscriptionsServiceRestInterceptor", +) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/base.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/base.py new file mode 100644 index 000000000000..a2c6e1432124 --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/base.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.apps.events_subscriptions_v1 import gapic_version as package_version +from google.apps.events_subscriptions_v1.types import ( + subscription_resource, + subscriptions_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +class SubscriptionsServiceTransport(abc.ABC): + """Abstract transport class for SubscriptionsService.""" + + AUTH_SCOPES = ( + "https://www.googleapis.com/auth/chat.bot", + "https://www.googleapis.com/auth/chat.memberships", + "https://www.googleapis.com/auth/chat.memberships.readonly", + "https://www.googleapis.com/auth/chat.messages", + "https://www.googleapis.com/auth/chat.messages.reactions", + "https://www.googleapis.com/auth/chat.messages.reactions.readonly", + "https://www.googleapis.com/auth/chat.messages.readonly", + "https://www.googleapis.com/auth/chat.spaces", + "https://www.googleapis.com/auth/chat.spaces.readonly", + "https://www.googleapis.com/auth/meetings.space.created", + "https://www.googleapis.com/auth/meetings.space.readonly", + ) + + DEFAULT_HOST: str = "workspaceevents.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'workspaceevents.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (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 + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_subscription: gapic_v1.method.wrap_method( + self.create_subscription, + default_timeout=60.0, + client_info=client_info, + ), + self.delete_subscription: gapic_v1.method.wrap_method( + self.delete_subscription, + default_timeout=60.0, + client_info=client_info, + ), + self.get_subscription: gapic_v1.method.wrap_method( + self.get_subscription, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.list_subscriptions: gapic_v1.method.wrap_method( + self.list_subscriptions, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.update_subscription: gapic_v1.method.wrap_method( + self.update_subscription, + default_timeout=60.0, + client_info=client_info, + ), + self.reactivate_subscription: gapic_v1.method.wrap_method( + self.reactivate_subscription, + default_timeout=60.0, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def create_subscription( + self, + ) -> Callable[ + [subscriptions_service.CreateSubscriptionRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def delete_subscription( + self, + ) -> Callable[ + [subscriptions_service.DeleteSubscriptionRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def get_subscription( + self, + ) -> Callable[ + [subscriptions_service.GetSubscriptionRequest], + Union[ + subscription_resource.Subscription, + Awaitable[subscription_resource.Subscription], + ], + ]: + raise NotImplementedError() + + @property + def list_subscriptions( + self, + ) -> Callable[ + [subscriptions_service.ListSubscriptionsRequest], + Union[ + subscriptions_service.ListSubscriptionsResponse, + Awaitable[subscriptions_service.ListSubscriptionsResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_subscription( + self, + ) -> Callable[ + [subscriptions_service.UpdateSubscriptionRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def reactivate_subscription( + self, + ) -> Callable[ + [subscriptions_service.ReactivateSubscriptionRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("SubscriptionsServiceTransport",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc.py new file mode 100644 index 000000000000..b0d457684884 --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc.py @@ -0,0 +1,462 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from typing import Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers, operations_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import grpc # type: ignore + +from google.apps.events_subscriptions_v1.types import ( + subscription_resource, + subscriptions_service, +) + +from .base import DEFAULT_CLIENT_INFO, SubscriptionsServiceTransport + + +class SubscriptionsServiceGrpcTransport(SubscriptionsServiceTransport): + """gRPC backend transport for SubscriptionsService. + + A service that manages subscriptions to Google Workspace + events. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "workspaceevents.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'workspaceevents.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the 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 a 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 + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + 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] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + 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: + # 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 + + 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 + + else: + 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 + ) + + # 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, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "workspaceevents.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + 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 + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient(self.grpc_channel) + + # Return the client from cache. + return self._operations_client + + @property + def create_subscription( + self, + ) -> Callable[ + [subscriptions_service.CreateSubscriptionRequest], operations_pb2.Operation + ]: + r"""Return a callable for the create subscription method over gRPC. + + Creates a Google Workspace subscription. To learn how to use + this method, see `Create a Google Workspace + subscription `__. + + Returns: + Callable[[~.CreateSubscriptionRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_subscription" not in self._stubs: + self._stubs["create_subscription"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/CreateSubscription", + request_serializer=subscriptions_service.CreateSubscriptionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_subscription"] + + @property + def delete_subscription( + self, + ) -> Callable[ + [subscriptions_service.DeleteSubscriptionRequest], operations_pb2.Operation + ]: + r"""Return a callable for the delete subscription method over gRPC. + + Deletes a Google Workspace subscription. To learn how to use + this method, see `Delete a Google Workspace + subscription `__. + + Returns: + Callable[[~.DeleteSubscriptionRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_subscription" not in self._stubs: + self._stubs["delete_subscription"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/DeleteSubscription", + request_serializer=subscriptions_service.DeleteSubscriptionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_subscription"] + + @property + def get_subscription( + self, + ) -> Callable[ + [subscriptions_service.GetSubscriptionRequest], + subscription_resource.Subscription, + ]: + r"""Return a callable for the get subscription method over gRPC. + + Gets details about a Google Workspace subscription. To learn how + to use this method, see `Get details about a Google Workspace + subscription `__. + + Returns: + Callable[[~.GetSubscriptionRequest], + ~.Subscription]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_subscription" not in self._stubs: + self._stubs["get_subscription"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/GetSubscription", + request_serializer=subscriptions_service.GetSubscriptionRequest.serialize, + response_deserializer=subscription_resource.Subscription.deserialize, + ) + return self._stubs["get_subscription"] + + @property + def list_subscriptions( + self, + ) -> Callable[ + [subscriptions_service.ListSubscriptionsRequest], + subscriptions_service.ListSubscriptionsResponse, + ]: + r"""Return a callable for the list subscriptions method over gRPC. + + Lists Google Workspace subscriptions. To learn how to use this + method, see `List Google Workspace + subscriptions `__. + + Returns: + Callable[[~.ListSubscriptionsRequest], + ~.ListSubscriptionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_subscriptions" not in self._stubs: + self._stubs["list_subscriptions"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/ListSubscriptions", + request_serializer=subscriptions_service.ListSubscriptionsRequest.serialize, + response_deserializer=subscriptions_service.ListSubscriptionsResponse.deserialize, + ) + return self._stubs["list_subscriptions"] + + @property + def update_subscription( + self, + ) -> Callable[ + [subscriptions_service.UpdateSubscriptionRequest], operations_pb2.Operation + ]: + r"""Return a callable for the update subscription method over gRPC. + + Updates or renews a Google Workspace subscription. To learn how + to use this method, see `Update or renew a Google Workspace + subscription `__. + + Returns: + Callable[[~.UpdateSubscriptionRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_subscription" not in self._stubs: + self._stubs["update_subscription"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/UpdateSubscription", + request_serializer=subscriptions_service.UpdateSubscriptionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_subscription"] + + @property + def reactivate_subscription( + self, + ) -> Callable[ + [subscriptions_service.ReactivateSubscriptionRequest], operations_pb2.Operation + ]: + r"""Return a callable for the reactivate subscription method over gRPC. + + Reactivates a suspended Google Workspace subscription. + + This method resets your subscription's ``State`` field to + ``ACTIVE``. Before you use this method, you must fix the error + that suspended the subscription. To learn how to use this + method, see `Reactivate a Google Workspace + subscription `__. + + Returns: + Callable[[~.ReactivateSubscriptionRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "reactivate_subscription" not in self._stubs: + self._stubs["reactivate_subscription"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/ReactivateSubscription", + request_serializer=subscriptions_service.ReactivateSubscriptionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["reactivate_subscription"] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("SubscriptionsServiceGrpcTransport",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc_asyncio.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..4ed43a674aef --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc_asyncio.py @@ -0,0 +1,467 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.apps.events_subscriptions_v1.types import ( + subscription_resource, + subscriptions_service, +) + +from .base import DEFAULT_CLIENT_INFO, SubscriptionsServiceTransport +from .grpc import SubscriptionsServiceGrpcTransport + + +class SubscriptionsServiceGrpcAsyncIOTransport(SubscriptionsServiceTransport): + """gRPC AsyncIO backend transport for SubscriptionsService. + + A service that manages subscriptions to Google Workspace + events. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "workspaceevents.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + 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 + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "workspaceevents.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'workspaceevents.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the 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 a 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 + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + 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] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + 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: + # 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 + 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 + + else: + 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 + ) + + # 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, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_subscription( + self, + ) -> Callable[ + [subscriptions_service.CreateSubscriptionRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the create subscription method over gRPC. + + Creates a Google Workspace subscription. To learn how to use + this method, see `Create a Google Workspace + subscription `__. + + Returns: + Callable[[~.CreateSubscriptionRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_subscription" not in self._stubs: + self._stubs["create_subscription"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/CreateSubscription", + request_serializer=subscriptions_service.CreateSubscriptionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_subscription"] + + @property + def delete_subscription( + self, + ) -> Callable[ + [subscriptions_service.DeleteSubscriptionRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the delete subscription method over gRPC. + + Deletes a Google Workspace subscription. To learn how to use + this method, see `Delete a Google Workspace + subscription `__. + + Returns: + Callable[[~.DeleteSubscriptionRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_subscription" not in self._stubs: + self._stubs["delete_subscription"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/DeleteSubscription", + request_serializer=subscriptions_service.DeleteSubscriptionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_subscription"] + + @property + def get_subscription( + self, + ) -> Callable[ + [subscriptions_service.GetSubscriptionRequest], + Awaitable[subscription_resource.Subscription], + ]: + r"""Return a callable for the get subscription method over gRPC. + + Gets details about a Google Workspace subscription. To learn how + to use this method, see `Get details about a Google Workspace + subscription `__. + + Returns: + Callable[[~.GetSubscriptionRequest], + Awaitable[~.Subscription]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_subscription" not in self._stubs: + self._stubs["get_subscription"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/GetSubscription", + request_serializer=subscriptions_service.GetSubscriptionRequest.serialize, + response_deserializer=subscription_resource.Subscription.deserialize, + ) + return self._stubs["get_subscription"] + + @property + def list_subscriptions( + self, + ) -> Callable[ + [subscriptions_service.ListSubscriptionsRequest], + Awaitable[subscriptions_service.ListSubscriptionsResponse], + ]: + r"""Return a callable for the list subscriptions method over gRPC. + + Lists Google Workspace subscriptions. To learn how to use this + method, see `List Google Workspace + subscriptions `__. + + Returns: + Callable[[~.ListSubscriptionsRequest], + Awaitable[~.ListSubscriptionsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_subscriptions" not in self._stubs: + self._stubs["list_subscriptions"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/ListSubscriptions", + request_serializer=subscriptions_service.ListSubscriptionsRequest.serialize, + response_deserializer=subscriptions_service.ListSubscriptionsResponse.deserialize, + ) + return self._stubs["list_subscriptions"] + + @property + def update_subscription( + self, + ) -> Callable[ + [subscriptions_service.UpdateSubscriptionRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the update subscription method over gRPC. + + Updates or renews a Google Workspace subscription. To learn how + to use this method, see `Update or renew a Google Workspace + subscription `__. + + Returns: + Callable[[~.UpdateSubscriptionRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_subscription" not in self._stubs: + self._stubs["update_subscription"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/UpdateSubscription", + request_serializer=subscriptions_service.UpdateSubscriptionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_subscription"] + + @property + def reactivate_subscription( + self, + ) -> Callable[ + [subscriptions_service.ReactivateSubscriptionRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the reactivate subscription method over gRPC. + + Reactivates a suspended Google Workspace subscription. + + This method resets your subscription's ``State`` field to + ``ACTIVE``. Before you use this method, you must fix the error + that suspended the subscription. To learn how to use this + method, see `Reactivate a Google Workspace + subscription `__. + + Returns: + Callable[[~.ReactivateSubscriptionRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "reactivate_subscription" not in self._stubs: + self._stubs["reactivate_subscription"] = self.grpc_channel.unary_unary( + "/google.apps.events.subscriptions.v1.SubscriptionsService/ReactivateSubscription", + request_serializer=subscriptions_service.ReactivateSubscriptionRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["reactivate_subscription"] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + +__all__ = ("SubscriptionsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/rest.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/rest.py new file mode 100644 index 000000000000..488b03b2364e --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/rest.py @@ -0,0 +1,1132 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# + +import dataclasses +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import ( + gapic_v1, + operations_v1, + path_template, + rest_helpers, + rest_streaming, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import json_format +import grpc # type: ignore +from requests import __version__ as requests_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + + +from google.longrunning import operations_pb2 # type: ignore + +from google.apps.events_subscriptions_v1.types import ( + subscription_resource, + subscriptions_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .base import SubscriptionsServiceTransport + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class SubscriptionsServiceRestInterceptor: + """Interceptor for SubscriptionsService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the SubscriptionsServiceRestTransport. + + .. code-block:: python + class MyCustomSubscriptionsServiceInterceptor(SubscriptionsServiceRestInterceptor): + def pre_create_subscription(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_subscription(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_subscription(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_delete_subscription(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_subscription(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_subscription(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_subscriptions(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_subscriptions(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_reactivate_subscription(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_reactivate_subscription(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_subscription(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_subscription(self, response): + logging.log(f"Received response: {response}") + return response + + transport = SubscriptionsServiceRestTransport(interceptor=MyCustomSubscriptionsServiceInterceptor()) + client = SubscriptionsServiceClient(transport=transport) + + + """ + + def pre_create_subscription( + self, + request: subscriptions_service.CreateSubscriptionRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + subscriptions_service.CreateSubscriptionRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for create_subscription + + Override in a subclass to manipulate the request or metadata + before they are sent to the SubscriptionsService server. + """ + return request, metadata + + def post_create_subscription( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_subscription + + Override in a subclass to manipulate the response + after it is returned by the SubscriptionsService server but before + it is returned to user code. + """ + return response + + def pre_delete_subscription( + self, + request: subscriptions_service.DeleteSubscriptionRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + subscriptions_service.DeleteSubscriptionRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for delete_subscription + + Override in a subclass to manipulate the request or metadata + before they are sent to the SubscriptionsService server. + """ + return request, metadata + + def post_delete_subscription( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for delete_subscription + + Override in a subclass to manipulate the response + after it is returned by the SubscriptionsService server but before + it is returned to user code. + """ + return response + + def pre_get_subscription( + self, + request: subscriptions_service.GetSubscriptionRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[subscriptions_service.GetSubscriptionRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_subscription + + Override in a subclass to manipulate the request or metadata + before they are sent to the SubscriptionsService server. + """ + return request, metadata + + def post_get_subscription( + self, response: subscription_resource.Subscription + ) -> subscription_resource.Subscription: + """Post-rpc interceptor for get_subscription + + Override in a subclass to manipulate the response + after it is returned by the SubscriptionsService server but before + it is returned to user code. + """ + return response + + def pre_list_subscriptions( + self, + request: subscriptions_service.ListSubscriptionsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + subscriptions_service.ListSubscriptionsRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for list_subscriptions + + Override in a subclass to manipulate the request or metadata + before they are sent to the SubscriptionsService server. + """ + return request, metadata + + def post_list_subscriptions( + self, response: subscriptions_service.ListSubscriptionsResponse + ) -> subscriptions_service.ListSubscriptionsResponse: + """Post-rpc interceptor for list_subscriptions + + Override in a subclass to manipulate the response + after it is returned by the SubscriptionsService server but before + it is returned to user code. + """ + return response + + def pre_reactivate_subscription( + self, + request: subscriptions_service.ReactivateSubscriptionRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + subscriptions_service.ReactivateSubscriptionRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for reactivate_subscription + + Override in a subclass to manipulate the request or metadata + before they are sent to the SubscriptionsService server. + """ + return request, metadata + + def post_reactivate_subscription( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for reactivate_subscription + + Override in a subclass to manipulate the response + after it is returned by the SubscriptionsService server but before + it is returned to user code. + """ + return response + + def pre_update_subscription( + self, + request: subscriptions_service.UpdateSubscriptionRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + subscriptions_service.UpdateSubscriptionRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for update_subscription + + Override in a subclass to manipulate the request or metadata + before they are sent to the SubscriptionsService server. + """ + return request, metadata + + def post_update_subscription( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for update_subscription + + Override in a subclass to manipulate the response + after it is returned by the SubscriptionsService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the SubscriptionsService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the SubscriptionsService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class SubscriptionsServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: SubscriptionsServiceRestInterceptor + + +class SubscriptionsServiceRestTransport(SubscriptionsServiceTransport): + """REST backend transport for SubscriptionsService. + + A service that manages subscriptions to Google Workspace + events. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__( + self, + *, + host: str = "workspaceevents.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[SubscriptionsServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'workspaceevents.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` 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 are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or SubscriptionsServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v1/{name=operations/**}", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _CreateSubscription(SubscriptionsServiceRestStub): + def __hash__(self): + return hash("CreateSubscription") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: subscriptions_service.CreateSubscriptionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the create subscription method over HTTP. + + Args: + request (~.subscriptions_service.CreateSubscriptionRequest): + The request object. The request message for + [SubscriptionsService.CreateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/subscriptions", + "body": "subscription", + }, + ] + request, metadata = self._interceptor.pre_create_subscription( + request, metadata + ) + pb_request = subscriptions_service.CreateSubscriptionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_subscription(resp) + return resp + + class _DeleteSubscription(SubscriptionsServiceRestStub): + def __hash__(self): + return hash("DeleteSubscription") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: subscriptions_service.DeleteSubscriptionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete subscription method over HTTP. + + Args: + request (~.subscriptions_service.DeleteSubscriptionRequest): + The request object. The request message for + [SubscriptionsService.DeleteSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=subscriptions/*}", + }, + ] + request, metadata = self._interceptor.pre_delete_subscription( + request, metadata + ) + pb_request = subscriptions_service.DeleteSubscriptionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_delete_subscription(resp) + return resp + + class _GetSubscription(SubscriptionsServiceRestStub): + def __hash__(self): + return hash("GetSubscription") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: subscriptions_service.GetSubscriptionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> subscription_resource.Subscription: + r"""Call the get subscription method over HTTP. + + Args: + request (~.subscriptions_service.GetSubscriptionRequest): + The request object. The request message for + [SubscriptionsService.GetSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.subscription_resource.Subscription: + A subscription to receive events about a Google + Workspace resource. To learn more about subscriptions, + see the `Google Workspace Events API + overview `__. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=subscriptions/*}", + }, + ] + request, metadata = self._interceptor.pre_get_subscription( + request, metadata + ) + pb_request = subscriptions_service.GetSubscriptionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = subscription_resource.Subscription() + pb_resp = subscription_resource.Subscription.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_subscription(resp) + return resp + + class _ListSubscriptions(SubscriptionsServiceRestStub): + def __hash__(self): + return hash("ListSubscriptions") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "filter": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: subscriptions_service.ListSubscriptionsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> subscriptions_service.ListSubscriptionsResponse: + r"""Call the list subscriptions method over HTTP. + + Args: + request (~.subscriptions_service.ListSubscriptionsRequest): + The request object. The request message for + [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.subscriptions_service.ListSubscriptionsResponse: + The response message for + [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/subscriptions", + }, + ] + request, metadata = self._interceptor.pre_list_subscriptions( + request, metadata + ) + pb_request = subscriptions_service.ListSubscriptionsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = subscriptions_service.ListSubscriptionsResponse() + pb_resp = subscriptions_service.ListSubscriptionsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_subscriptions(resp) + return resp + + class _ReactivateSubscription(SubscriptionsServiceRestStub): + def __hash__(self): + return hash("ReactivateSubscription") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: subscriptions_service.ReactivateSubscriptionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the reactivate subscription method over HTTP. + + Args: + request (~.subscriptions_service.ReactivateSubscriptionRequest): + The request object. The request message for + [SubscriptionsService.ReactivateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{name=subscriptions/*}:reactivate", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_reactivate_subscription( + request, metadata + ) + pb_request = subscriptions_service.ReactivateSubscriptionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_reactivate_subscription(resp) + return resp + + class _UpdateSubscription(SubscriptionsServiceRestStub): + def __hash__(self): + return hash("UpdateSubscription") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: subscriptions_service.UpdateSubscriptionRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the update subscription method over HTTP. + + Args: + request (~.subscriptions_service.UpdateSubscriptionRequest): + The request object. The request message for + [SubscriptionsService.UpdateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{subscription.name=subscriptions/*}", + "body": "subscription", + }, + ] + request, metadata = self._interceptor.pre_update_subscription( + request, metadata + ) + pb_request = subscriptions_service.UpdateSubscriptionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_subscription(resp) + return resp + + @property + def create_subscription( + self, + ) -> Callable[ + [subscriptions_service.CreateSubscriptionRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateSubscription(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_subscription( + self, + ) -> Callable[ + [subscriptions_service.DeleteSubscriptionRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteSubscription(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_subscription( + self, + ) -> Callable[ + [subscriptions_service.GetSubscriptionRequest], + subscription_resource.Subscription, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetSubscription(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_subscriptions( + self, + ) -> Callable[ + [subscriptions_service.ListSubscriptionsRequest], + subscriptions_service.ListSubscriptionsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListSubscriptions(self._session, self._host, self._interceptor) # type: ignore + + @property + def reactivate_subscription( + self, + ) -> Callable[ + [subscriptions_service.ReactivateSubscriptionRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ReactivateSubscription(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_subscription( + self, + ) -> Callable[ + [subscriptions_service.UpdateSubscriptionRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateSubscription(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(SubscriptionsServiceRestStub): + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=operations/**}", + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("SubscriptionsServiceRestTransport",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/__init__.py new file mode 100644 index 000000000000..ff5b123f73de --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/__init__.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from .subscription_resource import NotificationEndpoint, PayloadOptions, Subscription +from .subscriptions_service import ( + CreateSubscriptionMetadata, + CreateSubscriptionRequest, + DeleteSubscriptionMetadata, + DeleteSubscriptionRequest, + GetSubscriptionRequest, + ListSubscriptionsRequest, + ListSubscriptionsResponse, + ReactivateSubscriptionMetadata, + ReactivateSubscriptionRequest, + UpdateSubscriptionMetadata, + UpdateSubscriptionRequest, +) + +__all__ = ( + "NotificationEndpoint", + "PayloadOptions", + "Subscription", + "CreateSubscriptionMetadata", + "CreateSubscriptionRequest", + "DeleteSubscriptionMetadata", + "DeleteSubscriptionRequest", + "GetSubscriptionRequest", + "ListSubscriptionsRequest", + "ListSubscriptionsResponse", + "ReactivateSubscriptionMetadata", + "ReactivateSubscriptionRequest", + "UpdateSubscriptionMetadata", + "UpdateSubscriptionRequest", +) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscription_resource.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscription_resource.py new file mode 100644 index 000000000000..bebd284fa206 --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscription_resource.py @@ -0,0 +1,353 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.apps.events.subscriptions.v1", + manifest={ + "Subscription", + "PayloadOptions", + "NotificationEndpoint", + }, +) + + +class Subscription(proto.Message): + r"""A subscription to receive events about a Google Workspace resource. + To learn more about subscriptions, see the `Google Workspace Events + API + overview `__. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + expire_time (google.protobuf.timestamp_pb2.Timestamp): + Non-empty default. The timestamp in UTC when + the subscription expires. Always displayed on + output, regardless of what was used on input. + + This field is a member of `oneof`_ ``expiration``. + ttl (google.protobuf.duration_pb2.Duration): + Input only. The time-to-live (TTL) or duration for the + subscription. If unspecified or set to ``0``, uses the + maximum possible duration. + + This field is a member of `oneof`_ ``expiration``. + name (str): + Optional. Immutable. Identifier. Resource name of the + subscription. + + Format: ``subscriptions/{subscription}`` + uid (str): + Output only. System-assigned unique + identifier for the subscription. + target_resource (str): + Required. Immutable. The Google Workspace resource that's + monitored for events, formatted as the `full resource + name `__. To + learn about target resources, see `Supported Google + Workspace + resources `__. + + A user can only authorize your app to create one + subscription for a given target resource. If your app tries + to create another subscription with the same user + credentials, the request returns an ``ALREADY_EXISTS`` + error. + event_types (MutableSequence[str]): + Required. Immutable. Unordered list. Input for creating a + subscription. Otherwise, output only. One or more types of + events to receive about the target resource. Formatted + according to the CloudEvents specification. + + For a list of supported event types, see the following + documentation: + + - `Google Chat + events `__ + - `Google Meet + events `__ + + By default, you also receive events about the `lifecycle of + your + subscription `__. + You don't need to specify lifecycle events for this field. + + If you specify an event type that doesn't exist for the + target resource, the request returns an HTTP + ``400 Bad Request`` status code. + payload_options (google.apps.events_subscriptions_v1.types.PayloadOptions): + Optional. Options about what data to include + in the event payload. Only supported for Google + Chat events. + notification_endpoint (google.apps.events_subscriptions_v1.types.NotificationEndpoint): + Required. Immutable. The endpoint where the + subscription delivers events, such as a Pub/Sub + topic. + state (google.apps.events_subscriptions_v1.types.Subscription.State): + Output only. The state of the subscription. + Determines whether the subscription can receive + events and deliver them to the notification + endpoint. + suspension_reason (google.apps.events_subscriptions_v1.types.Subscription.ErrorType): + Output only. The error that suspended the subscription. + + To reactivate the subscription, resolve the error and call + the + [``ReactivateSubscription``][google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription] + method. + authority (str): + Output only. The user who authorized the creation of the + subscription. + + Format: ``users/{user}`` + + For Google Workspace users, the ``{user}`` value is the + ```user.id`` `__ + field from the Directory API. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time when the subscription + is created. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The last time that the + subscription is updated. + reconciling (bool): + Output only. If ``true``, the subscription is in the process + of being updated. + etag (str): + Optional. This checksum is computed by the + server based on the value of other fields, and + might be sent on update requests to ensure the + client has an up-to-date value before + proceeding. + """ + + class State(proto.Enum): + r"""Possible states for the subscription. + + Values: + STATE_UNSPECIFIED (0): + Default value. This value is unused. + ACTIVE (1): + The subscription is active and can receive + and deliver events to its notification endpoint. + SUSPENDED (2): + The subscription is unable to receive events due to an + error. To identify the error, see the + [``suspension_reason``][google.apps.events.subscriptions.v1.Subscription.suspension_reason] + field. + DELETED (3): + The subscription is deleted. + """ + STATE_UNSPECIFIED = 0 + ACTIVE = 1 + SUSPENDED = 2 + DELETED = 3 + + class ErrorType(proto.Enum): + r"""Possible errors for a subscription. + + Values: + ERROR_TYPE_UNSPECIFIED (0): + Default value. This value is unused. + USER_SCOPE_REVOKED (1): + The authorizing user has revoked the grant of one or more + OAuth scopes. To learn more about authorization for Google + Workspace, see `Configure the OAuth consent + screen `__. + RESOURCE_DELETED (2): + The target resource for the subscription no + longer exists. + USER_AUTHORIZATION_FAILURE (3): + The user that authorized the creation of the + subscription no longer has access to the + subscription's target resource. + ENDPOINT_PERMISSION_DENIED (4): + The Google Workspace application doesn't have + access to deliver events to your subscription's + notification endpoint. + ENDPOINT_NOT_FOUND (6): + The subscription's notification endpoint + doesn't exist, or the endpoint can't be found in + the Google Cloud project where you created the + subscription. + ENDPOINT_RESOURCE_EXHAUSTED (7): + The subscription's notification endpoint + failed to receive events due to insufficient + quota or reaching rate limiting. + OTHER (5): + An unidentified error has occurred. + """ + ERROR_TYPE_UNSPECIFIED = 0 + USER_SCOPE_REVOKED = 1 + RESOURCE_DELETED = 2 + USER_AUTHORIZATION_FAILURE = 3 + ENDPOINT_PERMISSION_DENIED = 4 + ENDPOINT_NOT_FOUND = 6 + ENDPOINT_RESOURCE_EXHAUSTED = 7 + OTHER = 5 + + expire_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=13, + oneof="expiration", + message=timestamp_pb2.Timestamp, + ) + ttl: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=14, + oneof="expiration", + message=duration_pb2.Duration, + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + uid: str = proto.Field( + proto.STRING, + number=2, + ) + target_resource: str = proto.Field( + proto.STRING, + number=4, + ) + event_types: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + payload_options: "PayloadOptions" = proto.Field( + proto.MESSAGE, + number=6, + message="PayloadOptions", + ) + notification_endpoint: "NotificationEndpoint" = proto.Field( + proto.MESSAGE, + number=7, + message="NotificationEndpoint", + ) + state: State = proto.Field( + proto.ENUM, + number=8, + enum=State, + ) + suspension_reason: ErrorType = proto.Field( + proto.ENUM, + number=18, + enum=ErrorType, + ) + authority: str = proto.Field( + proto.STRING, + number=10, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=11, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + reconciling: bool = proto.Field( + proto.BOOL, + number=15, + ) + etag: str = proto.Field( + proto.STRING, + number=17, + ) + + +class PayloadOptions(proto.Message): + r"""Options about what data to include in the event payload. Only + supported for Google Chat events. + + Attributes: + include_resource (bool): + Optional. Whether the event payload includes data about the + resource that changed. For example, for an event where a + Google Chat message was created, whether the payload + contains data about the + ```Message`` `__ + resource. If false, the event payload only includes the name + of the changed resource. + field_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. If ``include_resource`` is set to ``true``, the + list of fields to include in the event payload. Separate + fields with a comma. For example, to include a Google Chat + message's sender and create time, enter + ``message.sender,message.createTime``. If omitted, the + payload includes all fields for the resource. + + If you specify a field that doesn't exist for the resource, + the system ignores the field. + """ + + include_resource: bool = proto.Field( + proto.BOOL, + number=1, + ) + field_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class NotificationEndpoint(proto.Message): + r"""The endpoint where the subscription delivers events. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + pubsub_topic (str): + Immutable. The Cloud Pub/Sub topic that receives events for + the subscription. + + Format: ``projects/{project}/topics/{topic}`` + + You must create the topic in the same Google Cloud project + where you create this subscription. + + When the topic receives events, the events are encoded as + Cloud Pub/Sub messages. For details, see the `Google Cloud + Pub/Sub Protocol Binding for + CloudEvents `__. + + This field is a member of `oneof`_ ``endpoint``. + """ + + pubsub_topic: str = proto.Field( + proto.STRING, + number=1, + oneof="endpoint", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscriptions_service.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscriptions_service.py new file mode 100644 index 000000000000..4d6813fb0cf9 --- /dev/null +++ b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscriptions_service.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import field_mask_pb2 # type: ignore +import proto # type: ignore + +from google.apps.events_subscriptions_v1.types import subscription_resource + +__protobuf__ = proto.module( + package="google.apps.events.subscriptions.v1", + manifest={ + "CreateSubscriptionRequest", + "DeleteSubscriptionRequest", + "GetSubscriptionRequest", + "UpdateSubscriptionRequest", + "ReactivateSubscriptionRequest", + "ListSubscriptionsRequest", + "ListSubscriptionsResponse", + "UpdateSubscriptionMetadata", + "CreateSubscriptionMetadata", + "DeleteSubscriptionMetadata", + "ReactivateSubscriptionMetadata", + }, +) + + +class CreateSubscriptionRequest(proto.Message): + r"""The request message for + [SubscriptionsService.CreateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription]. + + Attributes: + subscription (google.apps.events_subscriptions_v1.types.Subscription): + Required. The subscription resource to + create. + validate_only (bool): + Optional. If set to ``true``, validates and previews the + request, but doesn't create the subscription. + """ + + subscription: subscription_resource.Subscription = proto.Field( + proto.MESSAGE, + number=1, + message=subscription_resource.Subscription, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class DeleteSubscriptionRequest(proto.Message): + r"""The request message for + [SubscriptionsService.DeleteSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription]. + + Attributes: + name (str): + Required. Resource name of the subscription to delete. + + Format: ``subscriptions/{subscription}`` + validate_only (bool): + Optional. If set to ``true``, validates and previews the + request, but doesn't delete the subscription. + allow_missing (bool): + Optional. If set to ``true`` and the subscription isn't + found, the request succeeds but doesn't delete the + subscription. + etag (str): + Optional. Etag of the subscription. + + If present, it must match with the server's etag. Otherwise, + request fails with the status ``ABORTED``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=2, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=3, + ) + etag: str = proto.Field( + proto.STRING, + number=4, + ) + + +class GetSubscriptionRequest(proto.Message): + r"""The request message for + [SubscriptionsService.GetSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription]. + + Attributes: + name (str): + Required. Resource name of the subscription. + + Format: ``subscriptions/{subscription}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateSubscriptionRequest(proto.Message): + r"""The request message for + [SubscriptionsService.UpdateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription]. + + Attributes: + subscription (google.apps.events_subscriptions_v1.types.Subscription): + Required. The subscription to update. + + The subscription's ``name`` field is used to identify the + subscription to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Required. The field to update. + + You can update one of the following fields in a + subscription: + + - [``expire_time``][google.apps.events.subscriptions.v1.Subscription.expire_time]: + The timestamp when the subscription expires. + - [``ttl``][google.apps.events.subscriptions.v1.Subscription.ttl]: + The time-to-live (TTL) or duration of the subscription. + validate_only (bool): + Optional. If set to ``true``, validates and previews the + request, but doesn't update the subscription. + """ + + subscription: subscription_resource.Subscription = proto.Field( + proto.MESSAGE, + number=1, + message=subscription_resource.Subscription, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class ReactivateSubscriptionRequest(proto.Message): + r"""The request message for + [SubscriptionsService.ReactivateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription]. + + Attributes: + name (str): + Required. Resource name of the subscription. + + Format: ``subscriptions/{subscription}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListSubscriptionsRequest(proto.Message): + r"""The request message for + [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. + + Attributes: + page_size (int): + Optional. The maximum number of subscriptions to return. The + service might return fewer than this value. + + If unspecified or set to ``0``, up to 50 subscriptions are + returned. + + The maximum value is 100. If you specify a value more than + 100, the system only returns 100 subscriptions. + page_token (str): + Optional. A page token, received from a + previous list subscriptions call. Provide this + parameter to retrieve the subsequent page. + + When paginating, the filter value should match + the call that provided the page token. Passing a + different value might lead to unexpected + results. + filter (str): + Required. A query filter. + + You can filter subscriptions by event type (``event_types``) + and target resource (``target_resource``). + + You must specify at least one event type in your query. To + filter for multiple event types, use the ``OR`` operator. + + To filter by both event type and target resource, use the + ``AND`` operator and specify the full resource name, such as + ``//chat.googleapis.com/spaces/{space}``. + + For example, the following queries are valid: + + :: + + event_types:"google.workspace.chat.membership.v1.updated" OR + event_types:"google.workspace.chat.message.v1.created" + + event_types:"google.workspace.chat.message.v1.created" AND + target_resource="//chat.googleapis.com/spaces/{space}" + + ( event_types:"google.workspace.chat.membership.v1.updated" OR + event_types:"google.workspace.chat.message.v1.created" ) AND + target_resource="//chat.googleapis.com/spaces/{space}" + + The server rejects invalid queries with an + ``INVALID_ARGUMENT`` error. + """ + + page_size: int = proto.Field( + proto.INT32, + number=1, + ) + page_token: str = proto.Field( + proto.STRING, + number=2, + ) + filter: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListSubscriptionsResponse(proto.Message): + r"""The response message for + [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. + + Attributes: + subscriptions (MutableSequence[google.apps.events_subscriptions_v1.types.Subscription]): + List of subscriptions. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + subscriptions: MutableSequence[ + subscription_resource.Subscription + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=subscription_resource.Subscription, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class UpdateSubscriptionMetadata(proto.Message): + r"""Metadata for UpdateSubscription LRO.""" + + +class CreateSubscriptionMetadata(proto.Message): + r"""Metadata for CreateSubscription LRO.""" + + +class DeleteSubscriptionMetadata(proto.Message): + r"""Metadata for DeleteSubscription LRO.""" + + +class ReactivateSubscriptionMetadata(proto.Message): + r"""Metadata for ReactivateSubscription LRO.""" + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-apps-events-subscriptions/mypy.ini b/packages/google-apps-events-subscriptions/mypy.ini new file mode 100644 index 000000000000..574c5aed394b --- /dev/null +++ b/packages/google-apps-events-subscriptions/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/packages/google-apps-events-subscriptions/noxfile.py b/packages/google-apps-events-subscriptions/noxfile.py new file mode 100644 index 000000000000..1e6cd48d0529 --- /dev/null +++ b/packages/google-apps-events-subscriptions/noxfile.py @@ -0,0 +1,428 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2023 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. + +# Generated by synthtool. DO NOT EDIT! + +from __future__ import absolute_import + +import os +import pathlib +import re +import shutil +from typing import Dict, List +import warnings + +import nox + +BLACK_VERSION = "black[jupyter]==23.7.0" +ISORT_VERSION = "isort==5.11.0" + +LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] + + +DEFAULT_PYTHON_VERSION = "3.10" + +UNIT_TEST_PYTHON_VERSIONS: List[str] = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] +UNIT_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "asyncmock", + "pytest", + "pytest-cov", + "pytest-asyncio", +] +UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_DEPENDENCIES: List[str] = [] +UNIT_TEST_EXTRAS: List[str] = [] +UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12"] +SYSTEM_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "pytest", + "google-cloud-testutils", +] +SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_EXTRAS: List[str] = [] +SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +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): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", BLACK_VERSION) + session.run( + "black", + "--check", + *LINT_PATHS, + ) + + session.run("flake8", "google", "tests") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + session.run( + "black", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run( + "isort", + "--fss", + *LINT_PATHS, + ) + session.run( + "black", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") + + +def install_unittest_dependencies(session, *constraints): + standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES + session.install(*standard_deps, *constraints) + + if UNIT_TEST_EXTERNAL_DEPENDENCIES: + warnings.warn( + "'unit_test_external_dependencies' is deprecated. Instead, please " + "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", + DeprecationWarning, + ) + session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_LOCAL_DEPENDENCIES: + session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_EXTRAS_BY_PYTHON: + extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif UNIT_TEST_EXTRAS: + extras = UNIT_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +def default(session): + # Install all test dependencies, then install this package in-place. + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + install_unittest_dependencies(session, "-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", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + os.path.join("tests", "unit"), + *session.posargs, + ) + + +@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) +def unit(session): + """Run the unit test suite.""" + default(session) + + +def install_systemtest_dependencies(session, *constraints): + # Use pre-release gRPC for system tests. + # Exclude version 1.52.0rc1 which has a known issue. + # See https://github.com/grpc/grpc/issues/32163 + session.install("--pre", "grpcio!=1.52.0rc1") + + session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: + session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_LOCAL_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTRAS_BY_PYTHON: + extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif SYSTEM_TEST_EXTRAS: + extras = SYSTEM_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@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") + + # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. + if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": + session.skip("RUN_SYSTEM_TESTS is set to false, skipping") + # 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) + # Sanity check: only run tests if found. + if not system_test_exists and not system_test_folder_exists: + session.skip("System tests were not found") + + install_systemtest_dependencies(session, "-c", constraints_path) + + # Run py.test against the system tests. + if system_test_exists: + 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", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def cover(session): + """Run the final coverage report. + + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=100") + + session.run("coverage", "erase") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "sphinx==4.5.0", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "gcp-sphinx-docfx-yaml", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python="3.12") +def prerelease_deps(session): + """Run all tests with prerelease versions of dependencies installed.""" + + # Install all dependencies + session.install("-e", ".[all, tests, tracing]") + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + system_deps_all = ( + SYSTEM_TEST_STANDARD_DEPENDENCIES + + SYSTEM_TEST_EXTERNAL_DEPENDENCIES + + SYSTEM_TEST_EXTRAS + ) + session.install(*system_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY + / "testing" + / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + session.install(*constraints_deps) + + prerel_deps = [ + "protobuf", + # dependency of grpc + "six", + "googleapis-common-protos", + # Exclude version 1.52.0rc1 which has a known issue. See https://github.com/grpc/grpc/issues/32163 + "grpcio!=1.52.0rc1", + "grpcio-status", + "google-api-core", + "google-auth", + "proto-plus", + "google-cloud-testutils", + # dependencies of google-cloud-testutils" + "click", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--upgrade", dep) + + # Remaining dependencies + other_deps = [ + "requests", + ] + session.install(*other_deps) + + # Print out prerelease package versions + session.run( + "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" + ) + session.run("python", "-c", "import grpc; print(grpc.__version__)") + session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + + session.run("py.test", "tests/unit") diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json b/packages/google-apps-events-subscriptions/samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json new file mode 100644 index 000000000000..ef49bdf7102e --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json @@ -0,0 +1,1005 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.apps.events.subscriptions.v1", + "version": "v1" + } + ], + "language": "PYTHON", + "name": "google-apps-events-subscriptions", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", + "shortName": "SubscriptionsServiceAsyncClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.create_subscription", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "CreateSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.CreateSubscriptionRequest" + }, + { + "name": "subscription", + "type": "google.apps.events_subscriptions_v1.types.Subscription" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "create_subscription" + }, + "description": "Sample for CreateSubscription", + "file": "workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", + "shortName": "SubscriptionsServiceClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.create_subscription", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "CreateSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.CreateSubscriptionRequest" + }, + { + "name": "subscription", + "type": "google.apps.events_subscriptions_v1.types.Subscription" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "create_subscription" + }, + "description": "Sample for CreateSubscription", + "file": "workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", + "shortName": "SubscriptionsServiceAsyncClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.delete_subscription", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "DeleteSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.DeleteSubscriptionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "delete_subscription" + }, + "description": "Sample for DeleteSubscription", + "file": "workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", + "shortName": "SubscriptionsServiceClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.delete_subscription", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "DeleteSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.DeleteSubscriptionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_subscription" + }, + "description": "Sample for DeleteSubscription", + "file": "workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", + "shortName": "SubscriptionsServiceAsyncClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.get_subscription", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "GetSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.GetSubscriptionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.apps.events_subscriptions_v1.types.Subscription", + "shortName": "get_subscription" + }, + "description": "Sample for GetSubscription", + "file": "workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_GetSubscription_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", + "shortName": "SubscriptionsServiceClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.get_subscription", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "GetSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.GetSubscriptionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.apps.events_subscriptions_v1.types.Subscription", + "shortName": "get_subscription" + }, + "description": "Sample for GetSubscription", + "file": "workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_GetSubscription_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", + "shortName": "SubscriptionsServiceAsyncClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.list_subscriptions", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "ListSubscriptions" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest" + }, + { + "name": "page_size", + "type": "int" + }, + { + "name": "page_token", + "type": "str" + }, + { + "name": "filter", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.apps.events_subscriptions_v1.services.subscriptions_service.pagers.ListSubscriptionsAsyncPager", + "shortName": "list_subscriptions" + }, + "description": "Sample for ListSubscriptions", + "file": "workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", + "shortName": "SubscriptionsServiceClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.list_subscriptions", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "ListSubscriptions" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest" + }, + { + "name": "page_size", + "type": "int" + }, + { + "name": "page_token", + "type": "str" + }, + { + "name": "filter", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.apps.events_subscriptions_v1.services.subscriptions_service.pagers.ListSubscriptionsPager", + "shortName": "list_subscriptions" + }, + "description": "Sample for ListSubscriptions", + "file": "workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", + "shortName": "SubscriptionsServiceAsyncClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.reactivate_subscription", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "ReactivateSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.ReactivateSubscriptionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "reactivate_subscription" + }, + "description": "Sample for ReactivateSubscription", + "file": "workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", + "shortName": "SubscriptionsServiceClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.reactivate_subscription", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "ReactivateSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.ReactivateSubscriptionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "reactivate_subscription" + }, + "description": "Sample for ReactivateSubscription", + "file": "workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", + "shortName": "SubscriptionsServiceAsyncClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.update_subscription", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "UpdateSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.UpdateSubscriptionRequest" + }, + { + "name": "subscription", + "type": "google.apps.events_subscriptions_v1.types.Subscription" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "update_subscription" + }, + "description": "Sample for UpdateSubscription", + "file": "workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", + "shortName": "SubscriptionsServiceClient" + }, + "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.update_subscription", + "method": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription", + "service": { + "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", + "shortName": "SubscriptionsService" + }, + "shortName": "UpdateSubscription" + }, + "parameters": [ + { + "name": "request", + "type": "google.apps.events_subscriptions_v1.types.UpdateSubscriptionRequest" + }, + { + "name": "subscription", + "type": "google.apps.events_subscriptions_v1.types.Subscription" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "update_subscription" + }, + "description": "Sample for UpdateSubscription", + "file": "workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py" + } + ] +} diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py new file mode 100644 index 000000000000..f1c3db149d0e --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +async def sample_create_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + subscription = events_subscriptions_v1.Subscription() + subscription.target_resource = "target_resource_value" + subscription.event_types = ['event_types_value1', 'event_types_value2'] + subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" + + request = events_subscriptions_v1.CreateSubscriptionRequest( + subscription=subscription, + ) + + # Make the request + operation = client.create_subscription(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py new file mode 100644 index 000000000000..0cfa43c88086 --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +def sample_create_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + subscription = events_subscriptions_v1.Subscription() + subscription.target_resource = "target_resource_value" + subscription.event_types = ['event_types_value1', 'event_types_value2'] + subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" + + request = events_subscriptions_v1.CreateSubscriptionRequest( + subscription=subscription, + ) + + # Make the request + operation = client.create_subscription(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_sync] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py new file mode 100644 index 000000000000..7b1a505e1de4 --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +async def sample_delete_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.DeleteSubscriptionRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_subscription(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py new file mode 100644 index 000000000000..aef41f38ee0b --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +def sample_delete_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.DeleteSubscriptionRequest( + name="name_value", + ) + + # Make the request + operation = client.delete_subscription(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_sync] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py new file mode 100644 index 000000000000..24fd9dced74d --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_GetSubscription_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +async def sample_get_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.GetSubscriptionRequest( + name="name_value", + ) + + # Make the request + response = await client.get_subscription(request=request) + + # Handle the response + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_GetSubscription_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py new file mode 100644 index 000000000000..1907421b0797 --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_GetSubscription_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +def sample_get_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.GetSubscriptionRequest( + name="name_value", + ) + + # Make the request + response = client.get_subscription(request=request) + + # Handle the response + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_GetSubscription_sync] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py new file mode 100644 index 000000000000..b9fa0148c6ba --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListSubscriptions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +async def sample_list_subscriptions(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.ListSubscriptionsRequest( + filter="filter_value", + ) + + # Make the request + page_result = client.list_subscriptions(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py new file mode 100644 index 000000000000..0befeb3b40b8 --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListSubscriptions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +def sample_list_subscriptions(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.ListSubscriptionsRequest( + filter="filter_value", + ) + + # Make the request + page_result = client.list_subscriptions(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_sync] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py new file mode 100644 index 000000000000..4b664d9ad0b1 --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ReactivateSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +async def sample_reactivate_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.ReactivateSubscriptionRequest( + name="name_value", + ) + + # Make the request + operation = client.reactivate_subscription(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py new file mode 100644 index 000000000000..82deada37c21 --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ReactivateSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +def sample_reactivate_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + request = events_subscriptions_v1.ReactivateSubscriptionRequest( + name="name_value", + ) + + # Make the request + operation = client.reactivate_subscription(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_sync] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py new file mode 100644 index 000000000000..abb3082ac2db --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +async def sample_update_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() + + # Initialize request argument(s) + subscription = events_subscriptions_v1.Subscription() + subscription.target_resource = "target_resource_value" + subscription.event_types = ['event_types_value1', 'event_types_value2'] + subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" + + request = events_subscriptions_v1.UpdateSubscriptionRequest( + subscription=subscription, + ) + + # Make the request + operation = client.update_subscription(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py new file mode 100644 index 000000000000..8d908b3d6ea6 --- /dev/null +++ b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSubscription +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-apps-events-subscriptions + + +# [START workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.apps import events_subscriptions_v1 + + +def sample_update_subscription(): + # Create a client + client = events_subscriptions_v1.SubscriptionsServiceClient() + + # Initialize request argument(s) + subscription = events_subscriptions_v1.Subscription() + subscription.target_resource = "target_resource_value" + subscription.event_types = ['event_types_value1', 'event_types_value2'] + subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" + + request = events_subscriptions_v1.UpdateSubscriptionRequest( + subscription=subscription, + ) + + # Make the request + operation = client.update_subscription(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_sync] diff --git a/packages/google-apps-events-subscriptions/scripts/decrypt-secrets.sh b/packages/google-apps-events-subscriptions/scripts/decrypt-secrets.sh new file mode 100755 index 000000000000..0018b421ddf8 --- /dev/null +++ b/packages/google-apps-events-subscriptions/scripts/decrypt-secrets.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright 2023 Google LLC All rights reserved. +# +# 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. + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ROOT=$( dirname "$DIR" ) + +# Work from the project root. +cd $ROOT + +# Prevent it from overriding files. +# We recommend that sample authors use their own service account files and cloud project. +# In that case, they are supposed to prepare these files by themselves. +if [[ -f "testing/test-env.sh" ]] || \ + [[ -f "testing/service-account.json" ]] || \ + [[ -f "testing/client-secrets.json" ]]; then + echo "One or more target files exist, aborting." + exit 1 +fi + +# Use SECRET_MANAGER_PROJECT if set, fallback to cloud-devrel-kokoro-resources. +PROJECT_ID="${SECRET_MANAGER_PROJECT:-cloud-devrel-kokoro-resources}" + +gcloud secrets versions access latest --secret="python-docs-samples-test-env" \ + --project="${PROJECT_ID}" \ + > testing/test-env.sh +gcloud secrets versions access latest \ + --secret="python-docs-samples-service-account" \ + --project="${PROJECT_ID}" \ + > testing/service-account.json +gcloud secrets versions access latest \ + --secret="python-docs-samples-client-secrets" \ + --project="${PROJECT_ID}" \ + > testing/client-secrets.json diff --git a/packages/google-apps-events-subscriptions/scripts/fixup_events_subscriptions_v1_keywords.py b/packages/google-apps-events-subscriptions/scripts/fixup_events_subscriptions_v1_keywords.py new file mode 100644 index 000000000000..749c9a3926fa --- /dev/null +++ b/packages/google-apps-events-subscriptions/scripts/fixup_events_subscriptions_v1_keywords.py @@ -0,0 +1,181 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +class events_subscriptionsCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'create_subscription': ('subscription', 'validate_only', ), + 'delete_subscription': ('name', 'validate_only', 'allow_missing', 'etag', ), + 'get_subscription': ('name', ), + 'list_subscriptions': ('filter', 'page_size', 'page_token', ), + 'reactivate_subscription': ('name', ), + 'update_subscription': ('subscription', 'update_mask', 'validate_only', ), + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=events_subscriptionsCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the events_subscriptions client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/packages/google-apps-events-subscriptions/setup.py b/packages/google-apps-events-subscriptions/setup.py new file mode 100644 index 000000000000..701e986c32eb --- /dev/null +++ b/packages/google-apps-events-subscriptions/setup.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import io +import os +import re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = "google-apps-events-subscriptions" + + +description = "Google Apps Events Subscriptions API client library" + +version = None + +with open( + os.path.join(package_root, "google/apps/events_subscriptions/gapic_version.py") +) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert len(version_candidates) == 1 + version = version_candidates[0] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 1.34.1, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "google-auth >= 2.14.1, <3.0.0dev", + "proto-plus >= 1.22.3, <2.0.0dev", + "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-events-subscriptions" + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package + for package in setuptools.find_namespace_packages() + if package.startswith("google") +] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache 2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + install_requires=dependencies, + include_package_data=True, + zip_safe=False, +) diff --git a/packages/google-apps-events-subscriptions/testing/.gitignore b/packages/google-apps-events-subscriptions/testing/.gitignore new file mode 100644 index 000000000000..b05fbd630881 --- /dev/null +++ b/packages/google-apps-events-subscriptions/testing/.gitignore @@ -0,0 +1,3 @@ +test-env.sh +service-account.json +client-secrets.json \ No newline at end of file diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.10.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.10.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-apps-events-subscriptions/testing/constraints-3.10.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.11.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.11.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-apps-events-subscriptions/testing/constraints-3.11.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.12.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.12.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-apps-events-subscriptions/testing/constraints-3.12.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.7.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.7.txt new file mode 100644 index 000000000000..b8a550c73855 --- /dev/null +++ b/packages/google-apps-events-subscriptions/testing/constraints-3.7.txt @@ -0,0 +1,10 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file. +# Pin the version to the lower bound. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", +# Then this file should have google-cloud-foo==1.14.0 +google-api-core==1.34.1 +google-auth==2.14.1 +proto-plus==1.22.3 +protobuf==3.19.5 diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.8.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.8.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-apps-events-subscriptions/testing/constraints-3.8.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.9.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.9.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/packages/google-apps-events-subscriptions/testing/constraints-3.9.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/packages/google-apps-events-subscriptions/tests/__init__.py b/packages/google-apps-events-subscriptions/tests/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-apps-events-subscriptions/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-apps-events-subscriptions/tests/unit/__init__.py b/packages/google-apps-events-subscriptions/tests/unit/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-apps-events-subscriptions/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-apps-events-subscriptions/tests/unit/gapic/__init__.py b/packages/google-apps-events-subscriptions/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-apps-events-subscriptions/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/__init__.py b/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/test_subscriptions_service.py b/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/test_subscriptions_service.py new file mode 100644 index 000000000000..91b4e72cae36 --- /dev/null +++ b/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/test_subscriptions_service.py @@ -0,0 +1,5833 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import Iterable +import json +import math + +from google.api_core import ( + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) +from google.api_core import api_core_version, client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import operation_async # type: ignore +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import json_format +from google.protobuf import timestamp_pb2 # type: ignore +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +from google.apps.events_subscriptions_v1.services.subscriptions_service import ( + SubscriptionsServiceAsyncClient, + SubscriptionsServiceClient, + pagers, + transports, +) +from google.apps.events_subscriptions_v1.types import ( + subscription_resource, + subscriptions_service, +) + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert SubscriptionsServiceClient._get_default_mtls_endpoint(None) is None + assert ( + SubscriptionsServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + SubscriptionsServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + SubscriptionsServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + SubscriptionsServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + SubscriptionsServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert SubscriptionsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert SubscriptionsServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert SubscriptionsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + SubscriptionsServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert SubscriptionsServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert SubscriptionsServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert SubscriptionsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + SubscriptionsServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert SubscriptionsServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert SubscriptionsServiceClient._get_client_cert_source(None, False) is None + assert ( + SubscriptionsServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + SubscriptionsServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + SubscriptionsServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + SubscriptionsServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + SubscriptionsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SubscriptionsServiceClient), +) +@mock.patch.object( + SubscriptionsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SubscriptionsServiceAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = SubscriptionsServiceClient._DEFAULT_UNIVERSE + default_endpoint = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + SubscriptionsServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + SubscriptionsServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == SubscriptionsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + SubscriptionsServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + SubscriptionsServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == SubscriptionsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + SubscriptionsServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == SubscriptionsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + SubscriptionsServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + SubscriptionsServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + SubscriptionsServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + SubscriptionsServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + SubscriptionsServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + SubscriptionsServiceClient._get_universe_domain(None, None) + == SubscriptionsServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + SubscriptionsServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceGrpcTransport, + "grpc", + ), + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceRestTransport, + "rest", + ), + ], +) +def test__validate_universe_domain(client_class, transport_class, transport_name): + client = client_class( + transport=transport_class(credentials=ga_credentials.AnonymousCredentials()) + ) + assert client._validate_universe_domain() == True + + # Test the case when universe is already validated. + assert client._validate_universe_domain() == True + + if transport_name == "grpc": + # Test the case where credentials are provided by the + # `local_channel_credentials`. The default universes in both match. + channel = grpc.secure_channel( + "http://localhost/", grpc.local_channel_credentials() + ) + client = client_class(transport=transport_class(channel=channel)) + assert client._validate_universe_domain() == True + + # Test the case where credentials do not exist: e.g. a transport is provided + # with no credentials. Validation should still succeed because there is no + # mismatch with non-existent credentials. + channel = grpc.secure_channel( + "http://localhost/", grpc.local_channel_credentials() + ) + transport = transport_class(channel=channel) + transport._credentials = None + client = client_class(transport=transport) + assert client._validate_universe_domain() == True + + # TODO: This is needed to cater for older versions of google-auth + # Make this test unconditional once the minimum supported version of + # google-auth becomes 2.23.0 or higher. + google_auth_major, google_auth_minor = [ + int(part) for part in google.auth.__version__.split(".")[0:2] + ] + if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): + credentials = ga_credentials.AnonymousCredentials() + credentials._universe_domain = "foo.com" + # Test the case when there is a universe mismatch from the credentials. + client = client_class(transport=transport_class(credentials=credentials)) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert ( + str(excinfo.value) + == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + ) + + # Test the case when there is a universe mismatch from the client. + # + # TODO: Make this test unconditional once the minimum supported version of + # google-api-core becomes 2.15.0 or higher. + api_core_major, api_core_minor = [ + int(part) for part in api_core_version.__version__.split(".")[0:2] + ] + if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): + client = client_class( + client_options={"universe_domain": "bar.com"}, + transport=transport_class( + credentials=ga_credentials.AnonymousCredentials(), + ), + ) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert ( + str(excinfo.value) + == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + ) + + # Test that ValueError is raised if universe_domain is provided via client options and credentials is None + with pytest.raises(ValueError): + client._compare_universes("foo.bar", None) + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (SubscriptionsServiceClient, "grpc"), + (SubscriptionsServiceAsyncClient, "grpc_asyncio"), + (SubscriptionsServiceClient, "rest"), + ], +) +def test_subscriptions_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_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, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "workspaceevents.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://workspaceevents.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.SubscriptionsServiceGrpcTransport, "grpc"), + (transports.SubscriptionsServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.SubscriptionsServiceRestTransport, "rest"), + ], +) +def test_subscriptions_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (SubscriptionsServiceClient, "grpc"), + (SubscriptionsServiceAsyncClient, "grpc_asyncio"), + (SubscriptionsServiceClient, "rest"), + ], +) +def test_subscriptions_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "workspaceevents.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://workspaceevents.googleapis.com" + ) + + +def test_subscriptions_service_client_get_transport_class(): + transport = SubscriptionsServiceClient.get_transport_class() + available_transports = [ + transports.SubscriptionsServiceGrpcTransport, + transports.SubscriptionsServiceRestTransport, + ] + assert transport in available_transports + + transport = SubscriptionsServiceClient.get_transport_class("grpc") + assert transport == transports.SubscriptionsServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceGrpcTransport, + "grpc", + ), + ( + SubscriptionsServiceAsyncClient, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + SubscriptionsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SubscriptionsServiceClient), +) +@mock.patch.object( + SubscriptionsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SubscriptionsServiceAsyncClient), +) +def test_subscriptions_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(SubscriptionsServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(SubscriptionsServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceGrpcTransport, + "grpc", + "true", + ), + ( + SubscriptionsServiceAsyncClient, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceGrpcTransport, + "grpc", + "false", + ), + ( + SubscriptionsServiceAsyncClient, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceRestTransport, + "rest", + "true", + ), + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + SubscriptionsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SubscriptionsServiceClient), +) +@mock.patch.object( + SubscriptionsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SubscriptionsServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_subscriptions_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + 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, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + 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=True, + ): + with mock.patch( + "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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + 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, + always_use_jwt_access=True, + api_audience=None, + ) + + # 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(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", [SubscriptionsServiceClient, SubscriptionsServiceAsyncClient] +) +@mock.patch.object( + SubscriptionsServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(SubscriptionsServiceClient), +) +@mock.patch.object( + SubscriptionsServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(SubscriptionsServiceAsyncClient), +) +def test_subscriptions_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize( + "client_class", [SubscriptionsServiceClient, SubscriptionsServiceAsyncClient] +) +@mock.patch.object( + SubscriptionsServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SubscriptionsServiceClient), +) +@mock.patch.object( + SubscriptionsServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SubscriptionsServiceAsyncClient), +) +def test_subscriptions_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = SubscriptionsServiceClient._DEFAULT_UNIVERSE + default_endpoint = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceGrpcTransport, + "grpc", + ), + ( + SubscriptionsServiceAsyncClient, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceRestTransport, + "rest", + ), + ], +) +def test_subscriptions_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + SubscriptionsServiceAsyncClient, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceRestTransport, + "rest", + None, + ), + ], +) +def test_subscriptions_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_subscriptions_service_client_client_options_from_dict(): + with mock.patch( + "google.apps.events_subscriptions_v1.services.subscriptions_service.transports.SubscriptionsServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = SubscriptionsServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + SubscriptionsServiceClient, + transports.SubscriptionsServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + SubscriptionsServiceAsyncClient, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_subscriptions_service_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "workspaceevents.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + "https://www.googleapis.com/auth/chat.bot", + "https://www.googleapis.com/auth/chat.memberships", + "https://www.googleapis.com/auth/chat.memberships.readonly", + "https://www.googleapis.com/auth/chat.messages", + "https://www.googleapis.com/auth/chat.messages.reactions", + "https://www.googleapis.com/auth/chat.messages.reactions.readonly", + "https://www.googleapis.com/auth/chat.messages.readonly", + "https://www.googleapis.com/auth/chat.spaces", + "https://www.googleapis.com/auth/chat.spaces.readonly", + "https://www.googleapis.com/auth/meetings.space.created", + "https://www.googleapis.com/auth/meetings.space.readonly", + ), + scopes=None, + default_host="workspaceevents.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.CreateSubscriptionRequest, + dict, + ], +) +def test_create_subscription(request_type, transport: str = "grpc"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.CreateSubscriptionRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_subscription_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 = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + client.create_subscription() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.CreateSubscriptionRequest() + + +@pytest.mark.asyncio +async def test_create_subscription_async( + transport: str = "grpc_asyncio", + request_type=subscriptions_service.CreateSubscriptionRequest, +): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.CreateSubscriptionRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_subscription_async_from_dict(): + await test_create_subscription_async(request_type=dict) + + +def test_create_subscription_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_subscription( + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].subscription + mock_val = subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ) + assert arg == mock_val + + +def test_create_subscription_flattened_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_subscription( + subscriptions_service.CreateSubscriptionRequest(), + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + ) + + +@pytest.mark.asyncio +async def test_create_subscription_flattened_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_subscription( + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].subscription + mock_val = subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_subscription_flattened_error_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_subscription( + subscriptions_service.CreateSubscriptionRequest(), + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.DeleteSubscriptionRequest, + dict, + ], +) +def test_delete_subscription(request_type, transport: str = "grpc"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.DeleteSubscriptionRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_subscription_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 = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + client.delete_subscription() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.DeleteSubscriptionRequest() + + +@pytest.mark.asyncio +async def test_delete_subscription_async( + transport: str = "grpc_asyncio", + request_type=subscriptions_service.DeleteSubscriptionRequest, +): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.delete_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.DeleteSubscriptionRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_delete_subscription_async_from_dict(): + await test_delete_subscription_async(request_type=dict) + + +def test_delete_subscription_field_headers(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = subscriptions_service.DeleteSubscriptionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_subscription_field_headers_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = subscriptions_service.DeleteSubscriptionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_subscription_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_subscription( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_subscription_flattened_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_subscription( + subscriptions_service.DeleteSubscriptionRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_subscription_flattened_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_subscription( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_subscription_flattened_error_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_subscription( + subscriptions_service.DeleteSubscriptionRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.GetSubscriptionRequest, + dict, + ], +) +def test_get_subscription(request_type, transport: str = "grpc"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = subscription_resource.Subscription( + name="name_value", + uid="uid_value", + target_resource="target_resource_value", + event_types=["event_types_value"], + state=subscription_resource.Subscription.State.ACTIVE, + suspension_reason=subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED, + authority="authority_value", + reconciling=True, + etag="etag_value", + ) + response = client.get_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.GetSubscriptionRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, subscription_resource.Subscription) + assert response.name == "name_value" + assert response.uid == "uid_value" + assert response.target_resource == "target_resource_value" + assert response.event_types == ["event_types_value"] + assert response.state == subscription_resource.Subscription.State.ACTIVE + assert ( + response.suspension_reason + == subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED + ) + assert response.authority == "authority_value" + assert response.reconciling is True + assert response.etag == "etag_value" + + +def test_get_subscription_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 = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: + client.get_subscription() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.GetSubscriptionRequest() + + +@pytest.mark.asyncio +async def test_get_subscription_async( + transport: str = "grpc_asyncio", + request_type=subscriptions_service.GetSubscriptionRequest, +): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + subscription_resource.Subscription( + name="name_value", + uid="uid_value", + target_resource="target_resource_value", + event_types=["event_types_value"], + state=subscription_resource.Subscription.State.ACTIVE, + suspension_reason=subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED, + authority="authority_value", + reconciling=True, + etag="etag_value", + ) + ) + response = await client.get_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.GetSubscriptionRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, subscription_resource.Subscription) + assert response.name == "name_value" + assert response.uid == "uid_value" + assert response.target_resource == "target_resource_value" + assert response.event_types == ["event_types_value"] + assert response.state == subscription_resource.Subscription.State.ACTIVE + assert ( + response.suspension_reason + == subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED + ) + assert response.authority == "authority_value" + assert response.reconciling is True + assert response.etag == "etag_value" + + +@pytest.mark.asyncio +async def test_get_subscription_async_from_dict(): + await test_get_subscription_async(request_type=dict) + + +def test_get_subscription_field_headers(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = subscriptions_service.GetSubscriptionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: + call.return_value = subscription_resource.Subscription() + client.get_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_subscription_field_headers_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = subscriptions_service.GetSubscriptionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + subscription_resource.Subscription() + ) + await client.get_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_subscription_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = subscription_resource.Subscription() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_subscription( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_subscription_flattened_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_subscription( + subscriptions_service.GetSubscriptionRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_subscription_flattened_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = subscription_resource.Subscription() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + subscription_resource.Subscription() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_subscription( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_subscription_flattened_error_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_subscription( + subscriptions_service.GetSubscriptionRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.ListSubscriptionsRequest, + dict, + ], +) +def test_list_subscriptions(request_type, transport: str = "grpc"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = subscriptions_service.ListSubscriptionsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_subscriptions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.ListSubscriptionsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSubscriptionsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_subscriptions_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 = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + client.list_subscriptions() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.ListSubscriptionsRequest() + + +@pytest.mark.asyncio +async def test_list_subscriptions_async( + transport: str = "grpc_asyncio", + request_type=subscriptions_service.ListSubscriptionsRequest, +): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + subscriptions_service.ListSubscriptionsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_subscriptions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.ListSubscriptionsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSubscriptionsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_subscriptions_async_from_dict(): + await test_list_subscriptions_async(request_type=dict) + + +def test_list_subscriptions_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = subscriptions_service.ListSubscriptionsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_subscriptions( + page_size=951, + page_token="page_token_value", + filter="filter_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].page_size + mock_val = 951 + assert arg == mock_val + arg = args[0].page_token + mock_val = "page_token_value" + assert arg == mock_val + arg = args[0].filter + mock_val = "filter_value" + assert arg == mock_val + + +def test_list_subscriptions_flattened_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_subscriptions( + subscriptions_service.ListSubscriptionsRequest(), + page_size=951, + page_token="page_token_value", + filter="filter_value", + ) + + +@pytest.mark.asyncio +async def test_list_subscriptions_flattened_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = subscriptions_service.ListSubscriptionsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + subscriptions_service.ListSubscriptionsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_subscriptions( + page_size=951, + page_token="page_token_value", + filter="filter_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].page_size + mock_val = 951 + assert arg == mock_val + arg = args[0].page_token + mock_val = "page_token_value" + assert arg == mock_val + arg = args[0].filter + mock_val = "filter_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_subscriptions_flattened_error_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_subscriptions( + subscriptions_service.ListSubscriptionsRequest(), + page_size=951, + page_token="page_token_value", + filter="filter_value", + ) + + +def test_list_subscriptions_pager(transport_name: str = "grpc"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + subscription_resource.Subscription(), + subscription_resource.Subscription(), + ], + next_page_token="abc", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[], + next_page_token="def", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + ], + next_page_token="ghi", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + subscription_resource.Subscription(), + ], + ), + RuntimeError, + ) + + metadata = () + pager = client.list_subscriptions(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, subscription_resource.Subscription) for i in results) + + +def test_list_subscriptions_pages(transport_name: str = "grpc"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + subscription_resource.Subscription(), + subscription_resource.Subscription(), + ], + next_page_token="abc", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[], + next_page_token="def", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + ], + next_page_token="ghi", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + subscription_resource.Subscription(), + ], + ), + RuntimeError, + ) + pages = list(client.list_subscriptions(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_subscriptions_async_pager(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + subscription_resource.Subscription(), + subscription_resource.Subscription(), + ], + next_page_token="abc", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[], + next_page_token="def", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + ], + next_page_token="ghi", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + subscription_resource.Subscription(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_subscriptions( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, subscription_resource.Subscription) for i in responses) + + +@pytest.mark.asyncio +async def test_list_subscriptions_async_pages(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_subscriptions), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + subscription_resource.Subscription(), + subscription_resource.Subscription(), + ], + next_page_token="abc", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[], + next_page_token="def", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + ], + next_page_token="ghi", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + subscription_resource.Subscription(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_subscriptions(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.UpdateSubscriptionRequest, + dict, + ], +) +def test_update_subscription(request_type, transport: str = "grpc"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.update_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.UpdateSubscriptionRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_update_subscription_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 = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + client.update_subscription() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.UpdateSubscriptionRequest() + + +@pytest.mark.asyncio +async def test_update_subscription_async( + transport: str = "grpc_asyncio", + request_type=subscriptions_service.UpdateSubscriptionRequest, +): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.update_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.UpdateSubscriptionRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_update_subscription_async_from_dict(): + await test_update_subscription_async(request_type=dict) + + +def test_update_subscription_field_headers(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = subscriptions_service.UpdateSubscriptionRequest() + + request.subscription.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "subscription.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_subscription_field_headers_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = subscriptions_service.UpdateSubscriptionRequest() + + request.subscription.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.update_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "subscription.name=name_value", + ) in kw["metadata"] + + +def test_update_subscription_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_subscription( + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].subscription + mock_val = subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ) + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_subscription_flattened_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_subscription( + subscriptions_service.UpdateSubscriptionRequest(), + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_subscription_flattened_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_subscription( + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].subscription + mock_val = subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ) + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_subscription_flattened_error_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_subscription( + subscriptions_service.UpdateSubscriptionRequest(), + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.ReactivateSubscriptionRequest, + dict, + ], +) +def test_reactivate_subscription(request_type, transport: str = "grpc"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reactivate_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.reactivate_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.ReactivateSubscriptionRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_reactivate_subscription_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 = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reactivate_subscription), "__call__" + ) as call: + client.reactivate_subscription() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.ReactivateSubscriptionRequest() + + +@pytest.mark.asyncio +async def test_reactivate_subscription_async( + transport: str = "grpc_asyncio", + request_type=subscriptions_service.ReactivateSubscriptionRequest, +): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reactivate_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.reactivate_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == subscriptions_service.ReactivateSubscriptionRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_reactivate_subscription_async_from_dict(): + await test_reactivate_subscription_async(request_type=dict) + + +def test_reactivate_subscription_field_headers(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = subscriptions_service.ReactivateSubscriptionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reactivate_subscription), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.reactivate_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_reactivate_subscription_field_headers_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = subscriptions_service.ReactivateSubscriptionRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reactivate_subscription), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.reactivate_subscription(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_reactivate_subscription_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reactivate_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.reactivate_subscription( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_reactivate_subscription_flattened_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.reactivate_subscription( + subscriptions_service.ReactivateSubscriptionRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_reactivate_subscription_flattened_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.reactivate_subscription), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.reactivate_subscription( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_reactivate_subscription_flattened_error_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.reactivate_subscription( + subscriptions_service.ReactivateSubscriptionRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.CreateSubscriptionRequest, + dict, + ], +) +def test_create_subscription_rest(request_type): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request_init["subscription"] = { + "expire_time": {"seconds": 751, "nanos": 543}, + "ttl": {"seconds": 751, "nanos": 543}, + "name": "name_value", + "uid": "uid_value", + "target_resource": "target_resource_value", + "event_types": ["event_types_value1", "event_types_value2"], + "payload_options": { + "include_resource": True, + "field_mask": {"paths": ["paths_value1", "paths_value2"]}, + }, + "notification_endpoint": {"pubsub_topic": "pubsub_topic_value"}, + "state": 1, + "suspension_reason": 1, + "authority": "authority_value", + "create_time": {}, + "update_time": {}, + "reconciling": True, + "etag": "etag_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = subscriptions_service.CreateSubscriptionRequest.meta.fields[ + "subscription" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["subscription"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["subscription"][field])): + del request_init["subscription"][field][i][subfield] + else: + del request_init["subscription"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_subscription(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_create_subscription_rest_required_fields( + request_type=subscriptions_service.CreateSubscriptionRequest, +): + transport_class = transports.SubscriptionsServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_subscription._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("validate_only",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_subscription(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_subscription_rest_unset_required_fields(): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_subscription._get_unset_required_fields({}) + assert set(unset_fields) == (set(("validateOnly",)) & set(("subscription",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_subscription_rest_interceptors(null_interceptor): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SubscriptionsServiceRestInterceptor(), + ) + client = SubscriptionsServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "post_create_subscription" + ) as post, mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "pre_create_subscription" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = subscriptions_service.CreateSubscriptionRequest.pb( + subscriptions_service.CreateSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = subscriptions_service.CreateSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.create_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_subscription_rest_bad_request( + transport: str = "rest", + request_type=subscriptions_service.CreateSubscriptionRequest, +): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_subscription(request) + + +def test_create_subscription_rest_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_subscription(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/subscriptions" % client.transport._host, args[1] + ) + + +def test_create_subscription_rest_flattened_error(transport: str = "rest"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_subscription( + subscriptions_service.CreateSubscriptionRequest(), + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + ) + + +def test_create_subscription_rest_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.DeleteSubscriptionRequest, + dict, + ], +) +def test_delete_subscription_rest(request_type): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "subscriptions/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_subscription(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_delete_subscription_rest_required_fields( + request_type=subscriptions_service.DeleteSubscriptionRequest, +): + transport_class = transports.SubscriptionsServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_subscription._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "allow_missing", + "etag", + "validate_only", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_subscription(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_subscription_rest_unset_required_fields(): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_subscription._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "allowMissing", + "etag", + "validateOnly", + ) + ) + & set(("name",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_subscription_rest_interceptors(null_interceptor): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SubscriptionsServiceRestInterceptor(), + ) + client = SubscriptionsServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "post_delete_subscription" + ) as post, mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "pre_delete_subscription" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = subscriptions_service.DeleteSubscriptionRequest.pb( + subscriptions_service.DeleteSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = subscriptions_service.DeleteSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.delete_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_subscription_rest_bad_request( + transport: str = "rest", + request_type=subscriptions_service.DeleteSubscriptionRequest, +): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "subscriptions/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_subscription(request) + + +def test_delete_subscription_rest_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "subscriptions/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_subscription(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=subscriptions/*}" % client.transport._host, args[1] + ) + + +def test_delete_subscription_rest_flattened_error(transport: str = "rest"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_subscription( + subscriptions_service.DeleteSubscriptionRequest(), + name="name_value", + ) + + +def test_delete_subscription_rest_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.GetSubscriptionRequest, + dict, + ], +) +def test_get_subscription_rest(request_type): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "subscriptions/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = subscription_resource.Subscription( + name="name_value", + uid="uid_value", + target_resource="target_resource_value", + event_types=["event_types_value"], + state=subscription_resource.Subscription.State.ACTIVE, + suspension_reason=subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED, + authority="authority_value", + reconciling=True, + etag="etag_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = subscription_resource.Subscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_subscription(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, subscription_resource.Subscription) + assert response.name == "name_value" + assert response.uid == "uid_value" + assert response.target_resource == "target_resource_value" + assert response.event_types == ["event_types_value"] + assert response.state == subscription_resource.Subscription.State.ACTIVE + assert ( + response.suspension_reason + == subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED + ) + assert response.authority == "authority_value" + assert response.reconciling is True + assert response.etag == "etag_value" + + +def test_get_subscription_rest_required_fields( + request_type=subscriptions_service.GetSubscriptionRequest, +): + transport_class = transports.SubscriptionsServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = subscription_resource.Subscription() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = subscription_resource.Subscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_subscription(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_subscription_rest_unset_required_fields(): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_subscription._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_subscription_rest_interceptors(null_interceptor): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SubscriptionsServiceRestInterceptor(), + ) + client = SubscriptionsServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "post_get_subscription" + ) as post, mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "pre_get_subscription" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = subscriptions_service.GetSubscriptionRequest.pb( + subscriptions_service.GetSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = subscription_resource.Subscription.to_json( + subscription_resource.Subscription() + ) + + request = subscriptions_service.GetSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = subscription_resource.Subscription() + + client.get_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_subscription_rest_bad_request( + transport: str = "rest", request_type=subscriptions_service.GetSubscriptionRequest +): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "subscriptions/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_subscription(request) + + +def test_get_subscription_rest_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = subscription_resource.Subscription() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "subscriptions/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = subscription_resource.Subscription.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_subscription(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=subscriptions/*}" % client.transport._host, args[1] + ) + + +def test_get_subscription_rest_flattened_error(transport: str = "rest"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_subscription( + subscriptions_service.GetSubscriptionRequest(), + name="name_value", + ) + + +def test_get_subscription_rest_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.ListSubscriptionsRequest, + dict, + ], +) +def test_list_subscriptions_rest(request_type): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = subscriptions_service.ListSubscriptionsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = subscriptions_service.ListSubscriptionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_subscriptions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSubscriptionsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_subscriptions_rest_required_fields( + request_type=subscriptions_service.ListSubscriptionsRequest, +): + transport_class = transports.SubscriptionsServiceRestTransport + + request_init = {} + request_init["filter"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "filter" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_subscriptions._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "filter" in jsonified_request + assert jsonified_request["filter"] == request_init["filter"] + + jsonified_request["filter"] = "filter_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_subscriptions._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "filter" in jsonified_request + assert jsonified_request["filter"] == "filter_value" + + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = subscriptions_service.ListSubscriptionsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = subscriptions_service.ListSubscriptionsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_subscriptions(request) + + expected_params = [ + ( + "filter", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_subscriptions_rest_unset_required_fields(): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_subscriptions._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("filter",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_subscriptions_rest_interceptors(null_interceptor): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SubscriptionsServiceRestInterceptor(), + ) + client = SubscriptionsServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "post_list_subscriptions" + ) as post, mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "pre_list_subscriptions" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = subscriptions_service.ListSubscriptionsRequest.pb( + subscriptions_service.ListSubscriptionsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = ( + subscriptions_service.ListSubscriptionsResponse.to_json( + subscriptions_service.ListSubscriptionsResponse() + ) + ) + + request = subscriptions_service.ListSubscriptionsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = subscriptions_service.ListSubscriptionsResponse() + + client.list_subscriptions( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_subscriptions_rest_bad_request( + transport: str = "rest", request_type=subscriptions_service.ListSubscriptionsRequest +): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_subscriptions(request) + + +def test_list_subscriptions_rest_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = subscriptions_service.ListSubscriptionsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + page_size=951, + page_token="page_token_value", + filter="filter_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = subscriptions_service.ListSubscriptionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_subscriptions(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/subscriptions" % client.transport._host, args[1] + ) + + +def test_list_subscriptions_rest_flattened_error(transport: str = "rest"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_subscriptions( + subscriptions_service.ListSubscriptionsRequest(), + page_size=951, + page_token="page_token_value", + filter="filter_value", + ) + + +def test_list_subscriptions_rest_pager(transport: str = "rest"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + subscription_resource.Subscription(), + subscription_resource.Subscription(), + ], + next_page_token="abc", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[], + next_page_token="def", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + ], + next_page_token="ghi", + ), + subscriptions_service.ListSubscriptionsResponse( + subscriptions=[ + subscription_resource.Subscription(), + subscription_resource.Subscription(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + subscriptions_service.ListSubscriptionsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {} + + pager = client.list_subscriptions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, subscription_resource.Subscription) for i in results) + + pages = list(client.list_subscriptions(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.UpdateSubscriptionRequest, + dict, + ], +) +def test_update_subscription_rest(request_type): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"subscription": {"name": "subscriptions/sample1"}} + request_init["subscription"] = { + "expire_time": {"seconds": 751, "nanos": 543}, + "ttl": {"seconds": 751, "nanos": 543}, + "name": "subscriptions/sample1", + "uid": "uid_value", + "target_resource": "target_resource_value", + "event_types": ["event_types_value1", "event_types_value2"], + "payload_options": { + "include_resource": True, + "field_mask": {"paths": ["paths_value1", "paths_value2"]}, + }, + "notification_endpoint": {"pubsub_topic": "pubsub_topic_value"}, + "state": 1, + "suspension_reason": 1, + "authority": "authority_value", + "create_time": {}, + "update_time": {}, + "reconciling": True, + "etag": "etag_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = subscriptions_service.UpdateSubscriptionRequest.meta.fields[ + "subscription" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["subscription"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["subscription"][field])): + del request_init["subscription"][field][i][subfield] + else: + del request_init["subscription"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_subscription(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_update_subscription_rest_required_fields( + request_type=subscriptions_service.UpdateSubscriptionRequest, +): + transport_class = transports.SubscriptionsServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_subscription._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "update_mask", + "validate_only", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_subscription(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_subscription_rest_unset_required_fields(): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_subscription._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "updateMask", + "validateOnly", + ) + ) + & set(("subscription",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_subscription_rest_interceptors(null_interceptor): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SubscriptionsServiceRestInterceptor(), + ) + client = SubscriptionsServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "post_update_subscription" + ) as post, mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "pre_update_subscription" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = subscriptions_service.UpdateSubscriptionRequest.pb( + subscriptions_service.UpdateSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = subscriptions_service.UpdateSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.update_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_subscription_rest_bad_request( + transport: str = "rest", + request_type=subscriptions_service.UpdateSubscriptionRequest, +): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"subscription": {"name": "subscriptions/sample1"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_subscription(request) + + +def test_update_subscription_rest_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"subscription": {"name": "subscriptions/sample1"}} + + # get truthy value for each flattened field + mock_args = dict( + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_subscription(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{subscription.name=subscriptions/*}" % client.transport._host, + args[1], + ) + + +def test_update_subscription_rest_flattened_error(transport: str = "rest"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_subscription( + subscriptions_service.UpdateSubscriptionRequest(), + subscription=subscription_resource.Subscription( + expire_time=timestamp_pb2.Timestamp(seconds=751) + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_subscription_rest_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + subscriptions_service.ReactivateSubscriptionRequest, + dict, + ], +) +def test_reactivate_subscription_rest(request_type): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "subscriptions/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.reactivate_subscription(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_reactivate_subscription_rest_required_fields( + request_type=subscriptions_service.ReactivateSubscriptionRequest, +): + transport_class = transports.SubscriptionsServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).reactivate_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).reactivate_subscription._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.reactivate_subscription(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_reactivate_subscription_rest_unset_required_fields(): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.reactivate_subscription._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_reactivate_subscription_rest_interceptors(null_interceptor): + transport = transports.SubscriptionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SubscriptionsServiceRestInterceptor(), + ) + client = SubscriptionsServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "post_reactivate_subscription" + ) as post, mock.patch.object( + transports.SubscriptionsServiceRestInterceptor, "pre_reactivate_subscription" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = subscriptions_service.ReactivateSubscriptionRequest.pb( + subscriptions_service.ReactivateSubscriptionRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = subscriptions_service.ReactivateSubscriptionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.reactivate_subscription( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_reactivate_subscription_rest_bad_request( + transport: str = "rest", + request_type=subscriptions_service.ReactivateSubscriptionRequest, +): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "subscriptions/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.reactivate_subscription(request) + + +def test_reactivate_subscription_rest_flattened(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "subscriptions/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.reactivate_subscription(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=subscriptions/*}:reactivate" % client.transport._host, args[1] + ) + + +def test_reactivate_subscription_rest_flattened_error(transport: str = "rest"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.reactivate_subscription( + subscriptions_service.ReactivateSubscriptionRequest(), + name="name_value", + ) + + +def test_reactivate_subscription_rest_error(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.SubscriptionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.SubscriptionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SubscriptionsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.SubscriptionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SubscriptionsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SubscriptionsServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.SubscriptionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SubscriptionsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.SubscriptionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = SubscriptionsServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.SubscriptionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.SubscriptionsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SubscriptionsServiceGrpcTransport, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + transports.SubscriptionsServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "rest", + ], +) +def test_transport_kind(transport_name): + transport = SubscriptionsServiceClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.SubscriptionsServiceGrpcTransport, + ) + + +def test_subscriptions_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.SubscriptionsServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_subscriptions_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.apps.events_subscriptions_v1.services.subscriptions_service.transports.SubscriptionsServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.SubscriptionsServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "create_subscription", + "delete_subscription", + "get_subscription", + "list_subscriptions", + "update_subscription", + "reactivate_subscription", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_subscriptions_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.apps.events_subscriptions_v1.services.subscriptions_service.transports.SubscriptionsServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SubscriptionsServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/chat.bot", + "https://www.googleapis.com/auth/chat.memberships", + "https://www.googleapis.com/auth/chat.memberships.readonly", + "https://www.googleapis.com/auth/chat.messages", + "https://www.googleapis.com/auth/chat.messages.reactions", + "https://www.googleapis.com/auth/chat.messages.reactions.readonly", + "https://www.googleapis.com/auth/chat.messages.readonly", + "https://www.googleapis.com/auth/chat.spaces", + "https://www.googleapis.com/auth/chat.spaces.readonly", + "https://www.googleapis.com/auth/meetings.space.created", + "https://www.googleapis.com/auth/meetings.space.readonly", + ), + quota_project_id="octopus", + ) + + +def test_subscriptions_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.apps.events_subscriptions_v1.services.subscriptions_service.transports.SubscriptionsServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SubscriptionsServiceTransport() + adc.assert_called_once() + + +def test_subscriptions_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + SubscriptionsServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/chat.bot", + "https://www.googleapis.com/auth/chat.memberships", + "https://www.googleapis.com/auth/chat.memberships.readonly", + "https://www.googleapis.com/auth/chat.messages", + "https://www.googleapis.com/auth/chat.messages.reactions", + "https://www.googleapis.com/auth/chat.messages.reactions.readonly", + "https://www.googleapis.com/auth/chat.messages.readonly", + "https://www.googleapis.com/auth/chat.spaces", + "https://www.googleapis.com/auth/chat.spaces.readonly", + "https://www.googleapis.com/auth/meetings.space.created", + "https://www.googleapis.com/auth/meetings.space.readonly", + ), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SubscriptionsServiceGrpcTransport, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + ], +) +def test_subscriptions_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( + "https://www.googleapis.com/auth/chat.bot", + "https://www.googleapis.com/auth/chat.memberships", + "https://www.googleapis.com/auth/chat.memberships.readonly", + "https://www.googleapis.com/auth/chat.messages", + "https://www.googleapis.com/auth/chat.messages.reactions", + "https://www.googleapis.com/auth/chat.messages.reactions.readonly", + "https://www.googleapis.com/auth/chat.messages.readonly", + "https://www.googleapis.com/auth/chat.spaces", + "https://www.googleapis.com/auth/chat.spaces.readonly", + "https://www.googleapis.com/auth/meetings.space.created", + "https://www.googleapis.com/auth/meetings.space.readonly", + ), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SubscriptionsServiceGrpcTransport, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + transports.SubscriptionsServiceRestTransport, + ], +) +def test_subscriptions_service_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.SubscriptionsServiceGrpcTransport, grpc_helpers), + (transports.SubscriptionsServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_subscriptions_service_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "workspaceevents.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + "https://www.googleapis.com/auth/chat.bot", + "https://www.googleapis.com/auth/chat.memberships", + "https://www.googleapis.com/auth/chat.memberships.readonly", + "https://www.googleapis.com/auth/chat.messages", + "https://www.googleapis.com/auth/chat.messages.reactions", + "https://www.googleapis.com/auth/chat.messages.reactions.readonly", + "https://www.googleapis.com/auth/chat.messages.readonly", + "https://www.googleapis.com/auth/chat.spaces", + "https://www.googleapis.com/auth/chat.spaces.readonly", + "https://www.googleapis.com/auth/meetings.space.created", + "https://www.googleapis.com/auth/meetings.space.readonly", + ), + scopes=["1", "2"], + default_host="workspaceevents.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SubscriptionsServiceGrpcTransport, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + ], +) +def test_subscriptions_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = ga_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=None, + 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_subscriptions_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.SubscriptionsServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_subscriptions_service_rest_lro_client(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_subscriptions_service_host_no_port(transport_name): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="workspaceevents.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "workspaceevents.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://workspaceevents.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_subscriptions_service_host_with_port(transport_name): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="workspaceevents.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "workspaceevents.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://workspaceevents.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_subscriptions_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = SubscriptionsServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = SubscriptionsServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_subscription._session + session2 = client2.transport.create_subscription._session + assert session1 != session2 + session1 = client1.transport.delete_subscription._session + session2 = client2.transport.delete_subscription._session + assert session1 != session2 + session1 = client1.transport.get_subscription._session + session2 = client2.transport.get_subscription._session + assert session1 != session2 + session1 = client1.transport.list_subscriptions._session + session2 = client2.transport.list_subscriptions._session + assert session1 != session2 + session1 = client1.transport.update_subscription._session + session2 = client2.transport.update_subscription._session + assert session1 != session2 + session1 = client1.transport.reactivate_subscription._session + session2 = client2.transport.reactivate_subscription._session + assert session1 != session2 + + +def test_subscriptions_service_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SubscriptionsServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_subscriptions_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SubscriptionsServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + 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", + [ + transports.SubscriptionsServiceGrpcTransport, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + ], +) +def test_subscriptions_service_transport_channel_mtls_with_client_cert_source( + transport_class, +): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + 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", + [ + transports.SubscriptionsServiceGrpcTransport, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + ], +) +def test_subscriptions_service_transport_channel_mtls_with_adc(transport_class): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_subscriptions_service_grpc_lro_client(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_subscriptions_service_grpc_lro_async_client(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_subscription_path(): + subscription = "squid" + expected = "subscriptions/{subscription}".format( + subscription=subscription, + ) + actual = SubscriptionsServiceClient.subscription_path(subscription) + assert expected == actual + + +def test_parse_subscription_path(): + expected = { + "subscription": "clam", + } + path = SubscriptionsServiceClient.subscription_path(**expected) + + # Check that the path construction is reversible. + actual = SubscriptionsServiceClient.parse_subscription_path(path) + assert expected == actual + + +def test_topic_path(): + project = "whelk" + topic = "octopus" + expected = "projects/{project}/topics/{topic}".format( + project=project, + topic=topic, + ) + actual = SubscriptionsServiceClient.topic_path(project, topic) + assert expected == actual + + +def test_parse_topic_path(): + expected = { + "project": "oyster", + "topic": "nudibranch", + } + path = SubscriptionsServiceClient.topic_path(**expected) + + # Check that the path construction is reversible. + actual = SubscriptionsServiceClient.parse_topic_path(path) + assert expected == actual + + +def test_user_path(): + user = "cuttlefish" + expected = "users/{user}".format( + user=user, + ) + actual = SubscriptionsServiceClient.user_path(user) + assert expected == actual + + +def test_parse_user_path(): + expected = { + "user": "mussel", + } + path = SubscriptionsServiceClient.user_path(**expected) + + # Check that the path construction is reversible. + actual = SubscriptionsServiceClient.parse_user_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "winkle" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = SubscriptionsServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nautilus", + } + path = SubscriptionsServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = SubscriptionsServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "scallop" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = SubscriptionsServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "abalone", + } + path = SubscriptionsServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = SubscriptionsServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "squid" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = SubscriptionsServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "clam", + } + path = SubscriptionsServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = SubscriptionsServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "whelk" + expected = "projects/{project}".format( + project=project, + ) + actual = SubscriptionsServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "octopus", + } + path = SubscriptionsServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = SubscriptionsServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "oyster" + location = "nudibranch" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = SubscriptionsServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + } + path = SubscriptionsServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = SubscriptionsServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.SubscriptionsServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.SubscriptionsServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = SubscriptionsServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_get_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.GetOperationRequest +): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({"name": "operations/sample1"}, request) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "operations/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation(transport: str = "grpc"): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc_asyncio"): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = SubscriptionsServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = SubscriptionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (SubscriptionsServiceClient, transports.SubscriptionsServiceGrpcTransport), + ( + SubscriptionsServiceAsyncClient, + transports.SubscriptionsServiceGrpcAsyncIOTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) From 456a190cb22638601a04063371ad2ead8a00319e Mon Sep 17 00:00:00 2001 From: yoshi-code-bot <70984784+yoshi-code-bot@users.noreply.github.com> Date: Thu, 29 Feb 2024 11:49:26 -0800 Subject: [PATCH 07/13] chore: Update release-please config files (#12375) Update release-please config files --- .release-please-manifest.json | 1 + release-please-config.json | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 6f428eaa2e2f..770b3738bdf4 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -3,6 +3,7 @@ "packages/google-analytics-admin": "0.22.6", "packages/google-analytics-data": "0.18.6", "packages/google-apps-card": "0.0.0", + "packages/google-apps-events-subscriptions": "0.0.0", "packages/google-apps-meet": "0.1.5", "packages/google-apps-script-type": "0.3.7", "packages/google-area120-tables": "0.11.8", diff --git a/release-please-config.json b/release-please-config.json index afa3f6ef0358..f880a3bf8ecd 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -80,6 +80,21 @@ ], "release-type": "python" }, + "packages/google-apps-events-subscriptions": { + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "component": "google-apps-events-subscriptions", + "extra-files": [ + "google/apps/events_subscriptions/gapic_version.py", + "google/apps/events_subscriptions_v1/gapic_version.py", + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json", + "type": "json" + } + ], + "release-type": "python" + }, "packages/google-apps-meet": { "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, From be31ec9c48409f5821d235c8597b12970b7c49e6 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Thu, 29 Feb 2024 18:25:16 -0500 Subject: [PATCH 08/13] chore(revert): revert add initial files for google.apps.events.subscriptions.v1 (#12377) Reverts googleapis/google-cloud-python#12374 See b/325289877 --- .../.OwlBot.yaml | 18 - .../.coveragerc | 13 - .../google-apps-events-subscriptions/.flake8 | 33 - .../.gitignore | 63 - .../.repo-metadata.json | 17 - .../CHANGELOG.md | 1 - .../CODE_OF_CONDUCT.md | 95 - .../CONTRIBUTING.rst | 271 - .../google-apps-events-subscriptions/LICENSE | 202 - .../MANIFEST.in | 25 - .../README.rst | 108 - .../docs/CHANGELOG.md | 1 - .../docs/README.rst | 1 - .../docs/_static/custom.css | 20 - .../docs/_templates/layout.html | 50 - .../docs/conf.py | 384 -- .../events_subscriptions_v1/services_.rst | 6 - .../subscriptions_service.rst | 10 - .../docs/events_subscriptions_v1/types_.rst | 6 - .../docs/index.rst | 23 - .../docs/multiprocessing.rst | 7 - .../apps/events_subscriptions/__init__.py | 63 - .../events_subscriptions/gapic_version.py | 16 - .../google/apps/events_subscriptions/py.typed | 2 - .../apps/events_subscriptions_v1/__init__.py | 61 - .../gapic_metadata.json | 118 - .../events_subscriptions_v1/gapic_version.py | 16 - .../apps/events_subscriptions_v1/py.typed | 2 - .../services/__init__.py | 15 - .../subscriptions_service/__init__.py | 22 - .../subscriptions_service/async_client.py | 1189 ---- .../services/subscriptions_service/client.py | 1609 ----- .../services/subscriptions_service/pagers.py | 162 - .../transports/__init__.py | 38 - .../subscriptions_service/transports/base.py | 283 - .../subscriptions_service/transports/grpc.py | 462 -- .../transports/grpc_asyncio.py | 467 -- .../subscriptions_service/transports/rest.py | 1132 ---- .../events_subscriptions_v1/types/__init__.py | 46 - .../types/subscription_resource.py | 353 - .../types/subscriptions_service.py | 297 - .../google-apps-events-subscriptions/mypy.ini | 3 - .../noxfile.py | 428 -- ...a_google.apps.events.subscriptions.v1.json | 1005 --- ...tions_service_create_subscription_async.py | 61 - ...ptions_service_create_subscription_sync.py | 61 - ...tions_service_delete_subscription_async.py | 56 - ...ptions_service_delete_subscription_sync.py | 56 - ...riptions_service_get_subscription_async.py | 52 - ...criptions_service_get_subscription_sync.py | 52 - ...ptions_service_list_subscriptions_async.py | 53 - ...iptions_service_list_subscriptions_sync.py | 53 - ...s_service_reactivate_subscription_async.py | 56 - ...ns_service_reactivate_subscription_sync.py | 56 - ...tions_service_update_subscription_async.py | 61 - ...ptions_service_update_subscription_sync.py | 61 - .../scripts/decrypt-secrets.sh | 46 - .../fixup_events_subscriptions_v1_keywords.py | 181 - .../google-apps-events-subscriptions/setup.py | 93 - .../testing/.gitignore | 3 - .../testing/constraints-3.10.txt | 6 - .../testing/constraints-3.11.txt | 6 - .../testing/constraints-3.12.txt | 6 - .../testing/constraints-3.7.txt | 10 - .../testing/constraints-3.8.txt | 6 - .../testing/constraints-3.9.txt | 6 - .../tests/__init__.py | 15 - .../tests/unit/__init__.py | 15 - .../tests/unit/gapic/__init__.py | 15 - .../gapic/events_subscriptions_v1/__init__.py | 15 - .../test_subscriptions_service.py | 5833 ----------------- 71 files changed, 16077 deletions(-) delete mode 100644 packages/google-apps-events-subscriptions/.OwlBot.yaml delete mode 100644 packages/google-apps-events-subscriptions/.coveragerc delete mode 100644 packages/google-apps-events-subscriptions/.flake8 delete mode 100644 packages/google-apps-events-subscriptions/.gitignore delete mode 100644 packages/google-apps-events-subscriptions/.repo-metadata.json delete mode 100644 packages/google-apps-events-subscriptions/CHANGELOG.md delete mode 100644 packages/google-apps-events-subscriptions/CODE_OF_CONDUCT.md delete mode 100644 packages/google-apps-events-subscriptions/CONTRIBUTING.rst delete mode 100644 packages/google-apps-events-subscriptions/LICENSE delete mode 100644 packages/google-apps-events-subscriptions/MANIFEST.in delete mode 100644 packages/google-apps-events-subscriptions/README.rst delete mode 120000 packages/google-apps-events-subscriptions/docs/CHANGELOG.md delete mode 120000 packages/google-apps-events-subscriptions/docs/README.rst delete mode 100644 packages/google-apps-events-subscriptions/docs/_static/custom.css delete mode 100644 packages/google-apps-events-subscriptions/docs/_templates/layout.html delete mode 100644 packages/google-apps-events-subscriptions/docs/conf.py delete mode 100644 packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/services_.rst delete mode 100644 packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/subscriptions_service.rst delete mode 100644 packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/types_.rst delete mode 100644 packages/google-apps-events-subscriptions/docs/index.rst delete mode 100644 packages/google-apps-events-subscriptions/docs/multiprocessing.rst delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions/__init__.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions/gapic_version.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions/py.typed delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_metadata.json delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_version.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/py.typed delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/__init__.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/__init__.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/async_client.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/client.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/pagers.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/__init__.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/base.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc_asyncio.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/rest.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/__init__.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscription_resource.py delete mode 100644 packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscriptions_service.py delete mode 100644 packages/google-apps-events-subscriptions/mypy.ini delete mode 100644 packages/google-apps-events-subscriptions/noxfile.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py delete mode 100644 packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py delete mode 100755 packages/google-apps-events-subscriptions/scripts/decrypt-secrets.sh delete mode 100644 packages/google-apps-events-subscriptions/scripts/fixup_events_subscriptions_v1_keywords.py delete mode 100644 packages/google-apps-events-subscriptions/setup.py delete mode 100644 packages/google-apps-events-subscriptions/testing/.gitignore delete mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.10.txt delete mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.11.txt delete mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.12.txt delete mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.7.txt delete mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.8.txt delete mode 100644 packages/google-apps-events-subscriptions/testing/constraints-3.9.txt delete mode 100644 packages/google-apps-events-subscriptions/tests/__init__.py delete mode 100644 packages/google-apps-events-subscriptions/tests/unit/__init__.py delete mode 100644 packages/google-apps-events-subscriptions/tests/unit/gapic/__init__.py delete mode 100644 packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/__init__.py delete mode 100644 packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/test_subscriptions_service.py diff --git a/packages/google-apps-events-subscriptions/.OwlBot.yaml b/packages/google-apps-events-subscriptions/.OwlBot.yaml deleted file mode 100644 index b29ae76b745b..000000000000 --- a/packages/google-apps-events-subscriptions/.OwlBot.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2022 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. - -deep-copy-regex: - - source: /google/apps/events/subscriptions/(v.*)/.*-py - dest: /owl-bot-staging/google-apps-events-subscriptions/$1 -api-name: google-apps-events-subscriptions diff --git a/packages/google-apps-events-subscriptions/.coveragerc b/packages/google-apps-events-subscriptions/.coveragerc deleted file mode 100644 index f7786672c12c..000000000000 --- a/packages/google-apps-events-subscriptions/.coveragerc +++ /dev/null @@ -1,13 +0,0 @@ -[run] -branch = True - -[report] -show_missing = True -omit = - google/apps/events_subscriptions/__init__.py - google/apps/events_subscriptions/gapic_version.py -exclude_lines = - # Re-enable the standard pragma - pragma: NO COVER - # Ignore debug-only repr - def __repr__ diff --git a/packages/google-apps-events-subscriptions/.flake8 b/packages/google-apps-events-subscriptions/.flake8 deleted file mode 100644 index 87f6e408c47d..000000000000 --- a/packages/google-apps-events-subscriptions/.flake8 +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2023 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. - -# Generated by synthtool. DO NOT EDIT! -[flake8] -ignore = E203, E231, E266, E501, W503 -exclude = - # Exclude generated code. - **/proto/** - **/gapic/** - **/services/** - **/types/** - *_pb2.py - - # Standard linting exemptions. - **/.nox/** - __pycache__, - .git, - *.pyc, - conf.py diff --git a/packages/google-apps-events-subscriptions/.gitignore b/packages/google-apps-events-subscriptions/.gitignore deleted file mode 100644 index b4243ced74e4..000000000000 --- a/packages/google-apps-events-subscriptions/.gitignore +++ /dev/null @@ -1,63 +0,0 @@ -*.py[cod] -*.sw[op] - -# C extensions -*.so - -# Packages -*.egg -*.egg-info -dist -build -eggs -.eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 -__pycache__ - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -.nox -.cache -.pytest_cache - - -# Mac -.DS_Store - -# JetBrains -.idea - -# VS Code -.vscode - -# emacs -*~ - -# Built documentation -docs/_build -bigquery/docs/generated -docs.metadata - -# Virtual environment -env/ - -# Test logs -coverage.xml -*sponge_log.xml - -# System test environment variables. -system_tests/local_test_setup - -# Make sure a generated file isn't accidentally committed. -pylintrc -pylintrc.test diff --git a/packages/google-apps-events-subscriptions/.repo-metadata.json b/packages/google-apps-events-subscriptions/.repo-metadata.json deleted file mode 100644 index f704766ed1fc..000000000000 --- a/packages/google-apps-events-subscriptions/.repo-metadata.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "google-apps-events-subscriptions", - "name_pretty": "Google Workspace Events API", - "api_description": "The Google Workspace Events API lets you subscribe to events and manage change notifications across Google Workspace applications.", - "product_documentation": "https://developers.google.com/workspace/events", - "client_documentation": "https://googleapis.dev/python/google-apps-events-subscriptions/latest", - "issue_tracker": "https://github.com/googleapis/google-cloud-python/issues", - "release_level": "preview", - "language": "python", - "library_type": "GAPIC_AUTO", - "repo": "googleapis/google-cloud-python", - "distribution_name": "google-apps-events-subscriptions", - "api_id": "subscriptions.googleapis.com", - "default_version": "v1", - "codeowner_team": "", - "api_shortname": "subscriptions" -} diff --git a/packages/google-apps-events-subscriptions/CHANGELOG.md b/packages/google-apps-events-subscriptions/CHANGELOG.md deleted file mode 100644 index 5ddad421e08f..000000000000 --- a/packages/google-apps-events-subscriptions/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -# Changelog \ No newline at end of file diff --git a/packages/google-apps-events-subscriptions/CODE_OF_CONDUCT.md b/packages/google-apps-events-subscriptions/CODE_OF_CONDUCT.md deleted file mode 100644 index 039f43681204..000000000000 --- a/packages/google-apps-events-subscriptions/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,95 +0,0 @@ - -# Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of -experience, education, socio-economic status, nationality, personal appearance, -race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, or to ban temporarily or permanently any -contributor for other behaviors that they deem inappropriate, threatening, -offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -This Code of Conduct also applies outside the project spaces when the Project -Steward has a reasonable belief that an individual's behavior may have a -negative impact on the project or its community. - -## Conflict Resolution - -We do not believe that all conflict is bad; healthy debate and disagreement -often yield positive results. However, it is never okay to be disrespectful or -to engage in behavior that violates the project’s code of conduct. - -If you see someone violating the code of conduct, you are encouraged to address -the behavior directly with those involved. Many issues can be resolved quickly -and easily, and this gives people more control over the outcome of their -dispute. If you are unable to resolve the matter for any reason, or if the -behavior is threatening or harassing, report it. We are dedicated to providing -an environment where participants feel welcome and safe. - - -Reports should be directed to *googleapis-stewards@google.com*, the -Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to -receive and address reported violations of the code of conduct. They will then -work with a committee consisting of representatives from the Open Source -Programs Office and the Google Open Source Strategy team. If for any reason you -are uncomfortable reaching out to the Project Steward, please email -opensource@google.com. - -We will investigate every complaint, but you may not receive a direct response. -We will use our discretion in determining when and how to follow up on reported -incidents, which may range from not taking action to permanent expulsion from -the project and project-sponsored spaces. We will notify the accused of the -report and provide them an opportunity to discuss it before any action is taken. -The identity of the reporter will be omitted from the details of the report -supplied to the accused. In potentially harmful situations, such as ongoing -harassment or threats to anyone's safety, we may take action without notice. - -## Attribution - -This Code of Conduct is adapted from the Contributor Covenant, version 1.4, -available at -https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/packages/google-apps-events-subscriptions/CONTRIBUTING.rst b/packages/google-apps-events-subscriptions/CONTRIBUTING.rst deleted file mode 100644 index 3e481e015da7..000000000000 --- a/packages/google-apps-events-subscriptions/CONTRIBUTING.rst +++ /dev/null @@ -1,271 +0,0 @@ -.. Generated by synthtool. DO NOT EDIT! -############ -Contributing -############ - -#. **Please sign one of the contributor license agreements below.** -#. Fork the repo, develop and test your code changes, add docs. -#. Make sure that your commit messages clearly describe the changes. -#. Send a pull request. (Please Read: `Faster Pull Request Reviews`_) - -.. _Faster Pull Request Reviews: https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#best-practices-for-faster-reviews - -.. contents:: Here are some guidelines for hacking on the Google Cloud Client libraries. - -*************** -Adding Features -*************** - -In order to add a feature: - -- The feature must be documented in both the API and narrative - documentation. - -- The feature must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 on both UNIX and Windows. - -- The feature must not add unnecessary dependencies (where - "unnecessary" is of course subjective, but new dependencies should - be discussed). - -**************************** -Using a Development Checkout -**************************** - -You'll have to create a development environment using a Git checkout: - -- While logged into your GitHub account, navigate to the - ``google-cloud-python`` `repo`_ on GitHub. - -- Fork and clone the ``google-cloud-python`` repository to your GitHub account by - clicking the "Fork" button. - -- Clone your fork of ``google-cloud-python`` from your GitHub account to your local - computer, substituting your account username and specifying the destination - as ``hack-on-google-cloud-python``. E.g.:: - - $ cd ${HOME} - $ git clone git@github.com:USERNAME/google-cloud-python.git hack-on-google-cloud-python - $ cd hack-on-google-cloud-python - # Configure remotes such that you can pull changes from the googleapis/google-cloud-python - # repository into your local repository. - $ git remote add upstream git@github.com:googleapis/google-cloud-python.git - # fetch and merge changes from upstream into main - $ git fetch upstream - $ git merge upstream/main - -Now your local repo is set up such that you will push changes to your GitHub -repo, from which you can submit a pull request. - -To work on the codebase and run the tests, we recommend using ``nox``, -but you can also use a ``virtualenv`` of your own creation. - -.. _repo: https://github.com/googleapis/google-cloud-python - -Using ``nox`` -============= - -We use `nox `__ to instrument our tests. - -- To test your changes, run unit tests with ``nox``:: - $ nox -s unit - -- To run a single unit test:: - - $ nox -s unit-3.12 -- -k - - - .. note:: - - The unit tests and system tests are described in the - ``noxfile.py`` files in each directory. - -.. nox: https://pypi.org/project/nox/ - -***************************************** -I'm getting weird errors... Can you help? -***************************************** - -If the error mentions ``Python.h`` not being found, -install ``python-dev`` and try again. -On Debian/Ubuntu:: - - $ sudo apt-get install python-dev - -************ -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 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:: - - $ nox -s lint - -- In order to make ``nox -s lint`` run faster, you can set some environment - variables:: - - export GOOGLE_CLOUD_TESTING_REMOTE="upstream" - export GOOGLE_CLOUD_TESTING_BRANCH="main" - - By doing this, you are specifying the location of the most up-to-date - version of ``google-cloud-python``. The - remote name ``upstream`` should point to the official ``googleapis`` - checkout and the branch should be the default branch on that remote (``main``). - -- This repository contains configuration for the - `pre-commit `__ tool, which automates checking - our linters during a commit. If you have it installed on your ``$PATH``, - you can enable enforcing those checks via: - -.. code-block:: bash - - $ pre-commit install - pre-commit installed at .git/hooks/pre-commit - -Exceptions to PEP8: - -- Many unit tests use a helper method, ``_call_fut`` ("FUT" is short for - "Function-Under-Test"), which is PEP8-incompliant, but more readable. - Some also use a local variable, ``MUT`` (short for "Module-Under-Test"). - -******************** -Running System Tests -******************** - -- To run system tests, you can execute:: - - # Run all system tests - $ nox -s system - - # Run a single system test - $ nox -s system-3.12 -- -k - - - .. note:: - - System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11 and 3.12. - 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 - auth settings and change some configuration in your project to - run all the tests. - -- System tests will be run against an actual project. You should use local credentials from gcloud when possible. See `Best practices for application authentication `__. Some tests require a service account. For those tests see `Authenticating as a service account `__. - -************* -Test Coverage -************* - -- The codebase *must* have 100% test statement coverage after each commit. - You can test coverage via ``nox -s cover``. - -****************************************************** -Documentation Coverage and Building HTML Documentation -****************************************************** - -If you fix a bug, and the bug requires an API or behavior modification, all -documentation in this package which references that API or behavior must be -changed to reflect the bug fix, ideally in the same commit that fixes the bug -or adds the feature. - -Build the docs via: - - $ nox -s docs - -************************* -Samples and code snippets -************************* - -Code samples and snippets live in the `samples/` catalogue. Feel free to -provide more examples, but make sure to write tests for those examples. -Each folder containing example code requires its own `noxfile.py` script -which automates testing. If you decide to create a new folder, you can -base it on the `samples/snippets` folder (providing `noxfile.py` and -the requirements files). - -The tests will run against a real Google Cloud Project, so you should -configure them just like the System Tests. - -- To run sample tests, you can execute:: - - # Run all tests in a folder - $ cd samples/snippets - $ nox -s py-3.8 - - # Run a single sample test - $ cd samples/snippets - $ nox -s py-3.8 -- -k - -******************************************** -Note About ``README`` as it pertains to PyPI -******************************************** - -The `description on PyPI`_ for the project comes directly from the -``README``. Due to the reStructuredText (``rst``) parser used by -PyPI, relative links which will work on GitHub (e.g. ``CONTRIBUTING.rst`` -instead of -``https://github.com/googleapis/google-cloud-python/blob/main/CONTRIBUTING.rst``) -may cause problems creating links or rendering the description. - -.. _description on PyPI: https://pypi.org/project/google-apps-events-subscriptions - - -************************* -Supported Python Versions -************************* - -We support: - -- `Python 3.7`_ -- `Python 3.8`_ -- `Python 3.9`_ -- `Python 3.10`_ -- `Python 3.11`_ -- `Python 3.12`_ - -.. _Python 3.7: https://docs.python.org/3.7/ -.. _Python 3.8: https://docs.python.org/3.8/ -.. _Python 3.9: https://docs.python.org/3.9/ -.. _Python 3.10: https://docs.python.org/3.10/ -.. _Python 3.11: https://docs.python.org/3.11/ -.. _Python 3.12: https://docs.python.org/3.12/ - - -Supported versions can be found in our ``noxfile.py`` `config`_. - -.. _config: https://github.com/googleapis/google-cloud-python/blob/main/packages/google-apps-events-subscriptions/noxfile.py - - -********** -Versioning -********** - -This library follows `Semantic Versioning`_. - -.. _Semantic Versioning: http://semver.org/ - -Some packages are currently in major version zero (``0.y.z``), which means that -anything may change at any time and the public API should not be considered -stable. - -****************************** -Contributor License Agreements -****************************** - -Before we can accept your pull requests you'll need to sign a Contributor -License Agreement (CLA): - -- **If you are an individual writing original source code** and **you own the - intellectual property**, then you'll need to sign an - `individual CLA `__. -- **If you work for a company that wants to allow you to contribute your work**, - then you'll need to sign a - `corporate CLA `__. - -You can sign these electronically (just scroll to the bottom). After that, -we'll be able to accept your pull requests. diff --git a/packages/google-apps-events-subscriptions/LICENSE b/packages/google-apps-events-subscriptions/LICENSE deleted file mode 100644 index d64569567334..000000000000 --- a/packages/google-apps-events-subscriptions/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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/packages/google-apps-events-subscriptions/MANIFEST.in b/packages/google-apps-events-subscriptions/MANIFEST.in deleted file mode 100644 index e0a66705318e..000000000000 --- a/packages/google-apps-events-subscriptions/MANIFEST.in +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2023 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. - -# Generated by synthtool. DO NOT EDIT! -include README.rst LICENSE -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 diff --git a/packages/google-apps-events-subscriptions/README.rst b/packages/google-apps-events-subscriptions/README.rst deleted file mode 100644 index 8a4284e93741..000000000000 --- a/packages/google-apps-events-subscriptions/README.rst +++ /dev/null @@ -1,108 +0,0 @@ -Python Client for Google Workspace Events API -============================================= - -|preview| |pypi| |versions| - -`Google Workspace Events API`_: The Google Workspace Events API lets you subscribe to events and manage change notifications across Google Workspace applications. - -- `Client Library Documentation`_ -- `Product Documentation`_ - -.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg - :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels -.. |pypi| image:: https://img.shields.io/pypi/v/google-apps-events-subscriptions.svg - :target: https://pypi.org/project/google-apps-events-subscriptions/ -.. |versions| image:: https://img.shields.io/pypi/pyversions/google-apps-events-subscriptions.svg - :target: https://pypi.org/project/google-apps-events-subscriptions/ -.. _Google Workspace Events API: https://developers.google.com/workspace/events -.. _Client Library Documentation: https://googleapis.dev/python/google-apps-events-subscriptions/latest -.. _Product Documentation: https://developers.google.com/workspace/events - -Quick Start ------------ - -In order to use this library, you first need to go through the following steps: - -1. `Select or create a Cloud Platform project.`_ -2. `Enable billing for your project.`_ -3. `Enable the Google Workspace Events API.`_ -4. `Setup Authentication.`_ - -.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project -.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project -.. _Enable the Google Workspace Events API.: https://developers.google.com/workspace/events -.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html - -Installation -~~~~~~~~~~~~ - -Install this library in a virtual environment using `venv`_. `venv`_ is a tool that -creates isolated Python environments. These isolated environments can have separate -versions of Python packages, which allows you to isolate one project's dependencies -from the dependencies of other projects. - -With `venv`_, it's possible to install this library without needing system -install permissions, and without clashing with the installed system -dependencies. - -.. _`venv`: https://docs.python.org/3/library/venv.html - - -Code samples and snippets -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Code samples and snippets live in the `samples/`_ folder. - -.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-events-subscriptions/samples - - -Supported Python Versions -^^^^^^^^^^^^^^^^^^^^^^^^^ -Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of -Python. - -Python >= 3.7 - -.. _active: https://devguide.python.org/devcycle/#in-development-main-branch -.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches - -Unsupported Python Versions -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Python <= 3.6 - -If you are using an `end-of-life`_ -version of Python, we recommend that you update as soon as possible to an actively supported version. - -.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches - -Mac/Linux -^^^^^^^^^ - -.. code-block:: console - - python3 -m venv - source /bin/activate - pip install google-apps-events-subscriptions - - -Windows -^^^^^^^ - -.. code-block:: console - - py -m venv - .\\Scripts\activate - pip install google-apps-events-subscriptions - -Next Steps -~~~~~~~~~~ - -- Read the `Client Library Documentation`_ for Google Workspace Events API - to see other available methods on the client. -- Read the `Google Workspace Events API Product documentation`_ to learn - more about the product and see How-to Guides. -- View this `README`_ to see the full list of Cloud - APIs that we cover. - -.. _Google Workspace Events API Product documentation: https://developers.google.com/workspace/events -.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst diff --git a/packages/google-apps-events-subscriptions/docs/CHANGELOG.md b/packages/google-apps-events-subscriptions/docs/CHANGELOG.md deleted file mode 120000 index 04c99a55caae..000000000000 --- a/packages/google-apps-events-subscriptions/docs/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -../CHANGELOG.md \ No newline at end of file diff --git a/packages/google-apps-events-subscriptions/docs/README.rst b/packages/google-apps-events-subscriptions/docs/README.rst deleted file mode 120000 index 89a0106941ff..000000000000 --- a/packages/google-apps-events-subscriptions/docs/README.rst +++ /dev/null @@ -1 +0,0 @@ -../README.rst \ No newline at end of file diff --git a/packages/google-apps-events-subscriptions/docs/_static/custom.css b/packages/google-apps-events-subscriptions/docs/_static/custom.css deleted file mode 100644 index b0a295464b23..000000000000 --- a/packages/google-apps-events-subscriptions/docs/_static/custom.css +++ /dev/null @@ -1,20 +0,0 @@ -div#python2-eol { - border-color: red; - border-width: medium; -} - -/* Ensure minimum width for 'Parameters' / 'Returns' column */ -dl.field-list > dt { - min-width: 100px -} - -/* Insert space between methods for readability */ -dl.method { - padding-top: 10px; - padding-bottom: 10px -} - -/* Insert empty space between classes */ -dl.class { - padding-bottom: 50px -} diff --git a/packages/google-apps-events-subscriptions/docs/_templates/layout.html b/packages/google-apps-events-subscriptions/docs/_templates/layout.html deleted file mode 100644 index 6316a537f72b..000000000000 --- a/packages/google-apps-events-subscriptions/docs/_templates/layout.html +++ /dev/null @@ -1,50 +0,0 @@ - -{% extends "!layout.html" %} -{%- block content %} -{%- if theme_fixed_sidebar|lower == 'true' %} -
- {{ sidebar() }} - {%- block document %} -
- {%- if render_sidebar %} -
- {%- endif %} - - {%- block relbar_top %} - {%- if theme_show_relbar_top|tobool %} - - {%- endif %} - {% endblock %} - -
-
- As of January 1, 2020 this library no longer supports Python 2 on the latest released version. - Library versions released prior to that date will continue to be available. For more information please - visit Python 2 support on Google Cloud. -
- {% block body %} {% endblock %} -
- - {%- block relbar_bottom %} - {%- if theme_show_relbar_bottom|tobool %} - - {%- endif %} - {% endblock %} - - {%- if render_sidebar %} -
- {%- endif %} -
- {%- endblock %} -
-
-{%- else %} -{{ super() }} -{%- endif %} -{%- endblock %} diff --git a/packages/google-apps-events-subscriptions/docs/conf.py b/packages/google-apps-events-subscriptions/docs/conf.py deleted file mode 100644 index 48e7a2ad38cf..000000000000 --- a/packages/google-apps-events-subscriptions/docs/conf.py +++ /dev/null @@ -1,384 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# google-apps-events-subscriptions documentation build configuration file -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import os -import shlex -import sys - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath("..")) - -# For plugins that can not read conf.py. -# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85 -sys.path.insert(0, os.path.abspath(".")) - -__version__ = "" - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = "1.5.5" - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.autosummary", - "sphinx.ext.intersphinx", - "sphinx.ext.coverage", - "sphinx.ext.doctest", - "sphinx.ext.napoleon", - "sphinx.ext.todo", - "sphinx.ext.viewcode", - "recommonmark", -] - -# autodoc/autosummary flags -autoclass_content = "both" -autodoc_default_options = {"members": True} -autosummary_generate = True - - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = [".rst", ".md"] - -# The encoding of source files. -# source_encoding = 'utf-8-sig' - -# The root toctree document. -root_doc = "index" - -# General information about the project. -project = "google-apps-events-subscriptions" -copyright = "2019, Google" -author = "Google APIs" - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The full version, including alpha/beta/rc tags. -release = __version__ -# The short X.Y version. -version = ".".join(release.split(".")[0:2]) - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# today = '' -# Else, today_fmt is used as the format for a strftime call. -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [ - "_build", - "**/.nox/**/*", - "samples/AUTHORING_GUIDE.md", - "samples/CONTRIBUTING.md", - "samples/snippets/README.rst", -] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = "alabaster" - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -html_theme_options = { - "description": "Google Cloud Client Libraries for google-apps-events-subscriptions", - "github_user": "googleapis", - "github_repo": "google-cloud-python", - "github_banner": True, - "font_family": "'Roboto', Georgia, sans", - "head_font_family": "'Roboto', Georgia, serif", - "code_font_family": "'Roboto Mono', 'Consolas', monospace", -} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -# html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -# html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -# html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -# html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = "google-apps-events-subscriptions-doc" - -# -- Options for warnings ------------------------------------------------------ - - -suppress_warnings = [ - # Temporarily suppress this to avoid "more than one target found for - # cross-reference" warning, which are intractable for us to avoid while in - # a mono-repo. - # See https://github.com/sphinx-doc/sphinx/blob - # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 - "ref.python" -] - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - #'preamble': '', - # Latex figure (float) alignment - #'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ( - root_doc, - "google-apps-events-subscriptions.tex", - "google-apps-events-subscriptions Documentation", - author, - "manual", - ) -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ( - root_doc, - "google-apps-events-subscriptions", - "google-apps-events-subscriptions Documentation", - [author], - 1, - ) -] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ( - root_doc, - "google-apps-events-subscriptions", - "google-apps-events-subscriptions Documentation", - author, - "google-apps-events-subscriptions", - "google-apps-events-subscriptions Library", - "APIs", - ) -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# texinfo_no_detailmenu = False - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = { - "python": ("https://python.readthedocs.org/en/latest/", None), - "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), - "google.api_core": ( - "https://googleapis.dev/python/google-api-core/latest/", - None, - ), - "grpc": ("https://grpc.github.io/grpc/python/", None), - "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), - "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), -} - - -# Napoleon settings -napoleon_google_docstring = True -napoleon_numpy_docstring = True -napoleon_include_private_with_doc = False -napoleon_include_special_with_doc = True -napoleon_use_admonition_for_examples = False -napoleon_use_admonition_for_notes = False -napoleon_use_admonition_for_references = False -napoleon_use_ivar = False -napoleon_use_param = True -napoleon_use_rtype = True diff --git a/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/services_.rst b/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/services_.rst deleted file mode 100644 index 8c1977ce4c50..000000000000 --- a/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/services_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Services for Google Apps Events Subscriptions v1 API -==================================================== -.. toctree:: - :maxdepth: 2 - - subscriptions_service diff --git a/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/subscriptions_service.rst b/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/subscriptions_service.rst deleted file mode 100644 index 66cad075bb1a..000000000000 --- a/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/subscriptions_service.rst +++ /dev/null @@ -1,10 +0,0 @@ -SubscriptionsService --------------------------------------- - -.. automodule:: google.apps.events_subscriptions_v1.services.subscriptions_service - :members: - :inherited-members: - -.. automodule:: google.apps.events_subscriptions_v1.services.subscriptions_service.pagers - :members: - :inherited-members: diff --git a/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/types_.rst b/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/types_.rst deleted file mode 100644 index c7c5912e59a6..000000000000 --- a/packages/google-apps-events-subscriptions/docs/events_subscriptions_v1/types_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Types for Google Apps Events Subscriptions v1 API -================================================= - -.. automodule:: google.apps.events_subscriptions_v1.types - :members: - :show-inheritance: diff --git a/packages/google-apps-events-subscriptions/docs/index.rst b/packages/google-apps-events-subscriptions/docs/index.rst deleted file mode 100644 index f07b4fce6385..000000000000 --- a/packages/google-apps-events-subscriptions/docs/index.rst +++ /dev/null @@ -1,23 +0,0 @@ -.. include:: README.rst - -.. include:: multiprocessing.rst - - -API Reference -------------- -.. toctree:: - :maxdepth: 2 - - events_subscriptions_v1/services_ - events_subscriptions_v1/types_ - - -Changelog ---------- - -For a list of all ``google-apps-events-subscriptions`` releases: - -.. toctree:: - :maxdepth: 2 - - CHANGELOG diff --git a/packages/google-apps-events-subscriptions/docs/multiprocessing.rst b/packages/google-apps-events-subscriptions/docs/multiprocessing.rst deleted file mode 100644 index 536d17b2ea65..000000000000 --- a/packages/google-apps-events-subscriptions/docs/multiprocessing.rst +++ /dev/null @@ -1,7 +0,0 @@ -.. note:: - - Because this client uses :mod:`grpc` library, it is safe to - share instances across threads. In multiprocessing scenarios, the best - practice is to create client instances *after* the invocation of - :func:`os.fork` by :class:`multiprocessing.pool.Pool` or - :class:`multiprocessing.Process`. diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/__init__.py deleted file mode 100644 index 852246f347b9..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/__init__.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from google.apps.events_subscriptions import gapic_version as package_version - -__version__ = package_version.__version__ - - -from google.apps.events_subscriptions_v1.services.subscriptions_service.async_client import ( - SubscriptionsServiceAsyncClient, -) -from google.apps.events_subscriptions_v1.services.subscriptions_service.client import ( - SubscriptionsServiceClient, -) -from google.apps.events_subscriptions_v1.types.subscription_resource import ( - NotificationEndpoint, - PayloadOptions, - Subscription, -) -from google.apps.events_subscriptions_v1.types.subscriptions_service import ( - CreateSubscriptionMetadata, - CreateSubscriptionRequest, - DeleteSubscriptionMetadata, - DeleteSubscriptionRequest, - GetSubscriptionRequest, - ListSubscriptionsRequest, - ListSubscriptionsResponse, - ReactivateSubscriptionMetadata, - ReactivateSubscriptionRequest, - UpdateSubscriptionMetadata, - UpdateSubscriptionRequest, -) - -__all__ = ( - "SubscriptionsServiceClient", - "SubscriptionsServiceAsyncClient", - "NotificationEndpoint", - "PayloadOptions", - "Subscription", - "CreateSubscriptionMetadata", - "CreateSubscriptionRequest", - "DeleteSubscriptionMetadata", - "DeleteSubscriptionRequest", - "GetSubscriptionRequest", - "ListSubscriptionsRequest", - "ListSubscriptionsResponse", - "ReactivateSubscriptionMetadata", - "ReactivateSubscriptionRequest", - "UpdateSubscriptionMetadata", - "UpdateSubscriptionRequest", -) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/gapic_version.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/gapic_version.py deleted file mode 100644 index 360a0d13ebdd..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/py.typed b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/py.typed deleted file mode 100644 index c814fdfb4bba..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-apps-events-subscriptions package uses inline types. diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py deleted file mode 100644 index e03a1415f0a6..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/__init__.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from google.apps.events_subscriptions_v1 import gapic_version as package_version - -__version__ = package_version.__version__ - - -from .services.subscriptions_service import ( - SubscriptionsServiceAsyncClient, - SubscriptionsServiceClient, -) -from .types.subscription_resource import ( - NotificationEndpoint, - PayloadOptions, - Subscription, -) -from .types.subscriptions_service import ( - CreateSubscriptionMetadata, - CreateSubscriptionRequest, - DeleteSubscriptionMetadata, - DeleteSubscriptionRequest, - GetSubscriptionRequest, - ListSubscriptionsRequest, - ListSubscriptionsResponse, - ReactivateSubscriptionMetadata, - ReactivateSubscriptionRequest, - UpdateSubscriptionMetadata, - UpdateSubscriptionRequest, -) - -__all__ = ( - "SubscriptionsServiceAsyncClient", - "CreateSubscriptionMetadata", - "CreateSubscriptionRequest", - "DeleteSubscriptionMetadata", - "DeleteSubscriptionRequest", - "GetSubscriptionRequest", - "ListSubscriptionsRequest", - "ListSubscriptionsResponse", - "NotificationEndpoint", - "PayloadOptions", - "ReactivateSubscriptionMetadata", - "ReactivateSubscriptionRequest", - "Subscription", - "SubscriptionsServiceClient", - "UpdateSubscriptionMetadata", - "UpdateSubscriptionRequest", -) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_metadata.json b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_metadata.json deleted file mode 100644 index f90006e089ce..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_metadata.json +++ /dev/null @@ -1,118 +0,0 @@ - { - "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", - "language": "python", - "libraryPackage": "google.apps.events_subscriptions_v1", - "protoPackage": "google.apps.events.subscriptions.v1", - "schema": "1.0", - "services": { - "SubscriptionsService": { - "clients": { - "grpc": { - "libraryClient": "SubscriptionsServiceClient", - "rpcs": { - "CreateSubscription": { - "methods": [ - "create_subscription" - ] - }, - "DeleteSubscription": { - "methods": [ - "delete_subscription" - ] - }, - "GetSubscription": { - "methods": [ - "get_subscription" - ] - }, - "ListSubscriptions": { - "methods": [ - "list_subscriptions" - ] - }, - "ReactivateSubscription": { - "methods": [ - "reactivate_subscription" - ] - }, - "UpdateSubscription": { - "methods": [ - "update_subscription" - ] - } - } - }, - "grpc-async": { - "libraryClient": "SubscriptionsServiceAsyncClient", - "rpcs": { - "CreateSubscription": { - "methods": [ - "create_subscription" - ] - }, - "DeleteSubscription": { - "methods": [ - "delete_subscription" - ] - }, - "GetSubscription": { - "methods": [ - "get_subscription" - ] - }, - "ListSubscriptions": { - "methods": [ - "list_subscriptions" - ] - }, - "ReactivateSubscription": { - "methods": [ - "reactivate_subscription" - ] - }, - "UpdateSubscription": { - "methods": [ - "update_subscription" - ] - } - } - }, - "rest": { - "libraryClient": "SubscriptionsServiceClient", - "rpcs": { - "CreateSubscription": { - "methods": [ - "create_subscription" - ] - }, - "DeleteSubscription": { - "methods": [ - "delete_subscription" - ] - }, - "GetSubscription": { - "methods": [ - "get_subscription" - ] - }, - "ListSubscriptions": { - "methods": [ - "list_subscriptions" - ] - }, - "ReactivateSubscription": { - "methods": [ - "reactivate_subscription" - ] - }, - "UpdateSubscription": { - "methods": [ - "update_subscription" - ] - } - } - } - } - } - } -} diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_version.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_version.py deleted file mode 100644 index 360a0d13ebdd..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/py.typed b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/py.typed deleted file mode 100644 index c814fdfb4bba..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-apps-events-subscriptions package uses inline types. diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/__init__.py deleted file mode 100644 index 89a37dc92c5a..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/__init__.py deleted file mode 100644 index c72dd2737d41..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from .async_client import SubscriptionsServiceAsyncClient -from .client import SubscriptionsServiceClient - -__all__ = ( - "SubscriptionsServiceClient", - "SubscriptionsServiceAsyncClient", -) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/async_client.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/async_client.py deleted file mode 100644 index 06b847e94cad..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/async_client.py +++ /dev/null @@ -1,1189 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from collections import OrderedDict -import functools -import re -from typing import ( - Dict, - Mapping, - MutableMapping, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, -) - -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.api_core.client_options import ClientOptions -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -from google.apps.events_subscriptions_v1 import gapic_version as package_version - -try: - OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.longrunning import operations_pb2 # type: ignore -from google.protobuf import duration_pb2 # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore - -from google.apps.events_subscriptions_v1.services.subscriptions_service import pagers -from google.apps.events_subscriptions_v1.types import ( - subscription_resource, - subscriptions_service, -) - -from .client import SubscriptionsServiceClient -from .transports.base import DEFAULT_CLIENT_INFO, SubscriptionsServiceTransport -from .transports.grpc_asyncio import SubscriptionsServiceGrpcAsyncIOTransport - - -class SubscriptionsServiceAsyncClient: - """A service that manages subscriptions to Google Workspace - events. - """ - - _client: SubscriptionsServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = SubscriptionsServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = SubscriptionsServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = SubscriptionsServiceClient._DEFAULT_UNIVERSE - - subscription_path = staticmethod(SubscriptionsServiceClient.subscription_path) - parse_subscription_path = staticmethod( - SubscriptionsServiceClient.parse_subscription_path - ) - topic_path = staticmethod(SubscriptionsServiceClient.topic_path) - parse_topic_path = staticmethod(SubscriptionsServiceClient.parse_topic_path) - user_path = staticmethod(SubscriptionsServiceClient.user_path) - parse_user_path = staticmethod(SubscriptionsServiceClient.parse_user_path) - common_billing_account_path = staticmethod( - SubscriptionsServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - SubscriptionsServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(SubscriptionsServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - SubscriptionsServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - SubscriptionsServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - SubscriptionsServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod(SubscriptionsServiceClient.common_project_path) - parse_common_project_path = staticmethod( - SubscriptionsServiceClient.parse_common_project_path - ) - common_location_path = staticmethod(SubscriptionsServiceClient.common_location_path) - parse_common_location_path = staticmethod( - SubscriptionsServiceClient.parse_common_location_path - ) - - @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: - SubscriptionsServiceAsyncClient: The constructed client. - """ - return SubscriptionsServiceClient.from_service_account_info.__func__(SubscriptionsServiceAsyncClient, 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: - SubscriptionsServiceAsyncClient: The constructed client. - """ - return SubscriptionsServiceClient.from_service_account_file.__func__(SubscriptionsServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return SubscriptionsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> SubscriptionsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SubscriptionsServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = functools.partial( - type(SubscriptionsServiceClient).get_transport_class, - type(SubscriptionsServiceClient), - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Union[str, SubscriptionsServiceTransport] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the subscriptions service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - 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, ~.SubscriptionsServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - 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: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = SubscriptionsServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - async def create_subscription( - self, - request: Optional[ - Union[subscriptions_service.CreateSubscriptionRequest, dict] - ] = None, - *, - subscription: Optional[subscription_resource.Subscription] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Creates a Google Workspace subscription. To learn how to use - this method, see `Create a Google Workspace - subscription `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - async def sample_create_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - subscription = events_subscriptions_v1.Subscription() - subscription.target_resource = "target_resource_value" - subscription.event_types = ['event_types_value1', 'event_types_value2'] - subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" - - request = events_subscriptions_v1.CreateSubscriptionRequest( - subscription=subscription, - ) - - # Make the request - operation = client.create_subscription(request=request) - - print("Waiting for operation to complete...") - - response = (await operation).result() - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.apps.events_subscriptions_v1.types.CreateSubscriptionRequest, dict]]): - The request object. The request message for - [SubscriptionsService.CreateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription]. - subscription (:class:`google.apps.events_subscriptions_v1.types.Subscription`): - Required. The subscription resource - to create. - - This corresponds to the ``subscription`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.api_core.operation_async.AsyncOperation: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn - more about subscriptions, see the [Google Workspace - Events API - overview](\ https://developers.google.com/workspace/events/guides). - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([subscription]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - request = subscriptions_service.CreateSubscriptionRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if subscription is not None: - request.subscription = subscription - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.create_subscription, - default_timeout=60.0, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - subscription_resource.Subscription, - metadata_type=subscriptions_service.CreateSubscriptionMetadata, - ) - - # Done; return the response. - return response - - async def delete_subscription( - self, - request: Optional[ - Union[subscriptions_service.DeleteSubscriptionRequest, dict] - ] = None, - *, - name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Deletes a Google Workspace subscription. To learn how to use - this method, see `Delete a Google Workspace - subscription `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - async def sample_delete_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.DeleteSubscriptionRequest( - name="name_value", - ) - - # Make the request - operation = client.delete_subscription(request=request) - - print("Waiting for operation to complete...") - - response = (await operation).result() - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.apps.events_subscriptions_v1.types.DeleteSubscriptionRequest, dict]]): - The request object. The request message for - [SubscriptionsService.DeleteSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription]. - name (:class:`str`): - Required. Resource name of the subscription to delete. - - Format: ``subscriptions/{subscription}`` - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.api_core.operation_async.AsyncOperation: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - request = subscriptions_service.DeleteSubscriptionRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.delete_subscription, - default_timeout=60.0, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - empty_pb2.Empty, - metadata_type=subscriptions_service.DeleteSubscriptionMetadata, - ) - - # Done; return the response. - return response - - async def get_subscription( - self, - request: Optional[ - Union[subscriptions_service.GetSubscriptionRequest, dict] - ] = None, - *, - name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> subscription_resource.Subscription: - r"""Gets details about a Google Workspace subscription. To learn how - to use this method, see `Get details about a Google Workspace - subscription `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - async def sample_get_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.GetSubscriptionRequest( - name="name_value", - ) - - # Make the request - response = await client.get_subscription(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.apps.events_subscriptions_v1.types.GetSubscriptionRequest, dict]]): - The request object. The request message for - [SubscriptionsService.GetSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription]. - name (:class:`str`): - Required. Resource name of the subscription. - - Format: ``subscriptions/{subscription}`` - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.apps.events_subscriptions_v1.types.Subscription: - A subscription to receive events about a Google Workspace resource. To learn - more about subscriptions, see the [Google Workspace - Events API - overview](\ https://developers.google.com/workspace/events/guides). - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - request = subscriptions_service.GetSubscriptionRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.get_subscription, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_subscriptions( - self, - request: Optional[ - Union[subscriptions_service.ListSubscriptionsRequest, dict] - ] = None, - *, - page_size: Optional[int] = None, - page_token: Optional[str] = None, - filter: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListSubscriptionsAsyncPager: - r"""Lists Google Workspace subscriptions. To learn how to use this - method, see `List Google Workspace - subscriptions `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - async def sample_list_subscriptions(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.ListSubscriptionsRequest( - filter="filter_value", - ) - - # Make the request - page_result = client.list_subscriptions(request=request) - - # Handle the response - async for response in page_result: - print(response) - - Args: - request (Optional[Union[google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest, dict]]): - The request object. The request message for - [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. - page_size (:class:`int`): - Optional. The maximum number of subscriptions to return. - The service might return fewer than this value. - - If unspecified or set to ``0``, up to 50 subscriptions - are returned. - - The maximum value is 100. If you specify a value more - than 100, the system only returns 100 subscriptions. - - This corresponds to the ``page_size`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - page_token (:class:`str`): - Optional. A page token, received from - a previous list subscriptions call. - Provide this parameter to retrieve the - subsequent page. - - When paginating, the filter value should - match the call that provided the page - token. Passing a different value might - lead to unexpected results. - - This corresponds to the ``page_token`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - filter (:class:`str`): - Required. A query filter. - - You can filter subscriptions by event type - (``event_types``) and target resource - (``target_resource``). - - You must specify at least one event type in your query. - To filter for multiple event types, use the ``OR`` - operator. - - To filter by both event type and target resource, use - the ``AND`` operator and specify the full resource name, - such as ``//chat.googleapis.com/spaces/{space}``. - - For example, the following queries are valid: - - :: - - event_types:"google.workspace.chat.membership.v1.updated" OR - event_types:"google.workspace.chat.message.v1.created" - - event_types:"google.workspace.chat.message.v1.created" AND - target_resource="//chat.googleapis.com/spaces/{space}" - - ( event_types:"google.workspace.chat.membership.v1.updated" OR - event_types:"google.workspace.chat.message.v1.created" ) AND - target_resource="//chat.googleapis.com/spaces/{space}" - - The server rejects invalid queries with an - ``INVALID_ARGUMENT`` error. - - This corresponds to the ``filter`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.apps.events_subscriptions_v1.services.subscriptions_service.pagers.ListSubscriptionsAsyncPager: - The response message for - [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([page_size, page_token, filter]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - request = subscriptions_service.ListSubscriptionsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if page_size is not None: - request.page_size = page_size - if page_token is not None: - request.page_token = page_token - if filter is not None: - request.filter = filter - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.list_subscriptions, - default_retry=retries.AsyncRetry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.ListSubscriptionsAsyncPager( - method=rpc, - request=request, - response=response, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def update_subscription( - self, - request: Optional[ - Union[subscriptions_service.UpdateSubscriptionRequest, dict] - ] = None, - *, - subscription: Optional[subscription_resource.Subscription] = None, - update_mask: Optional[field_mask_pb2.FieldMask] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Updates or renews a Google Workspace subscription. To learn how - to use this method, see `Update or renew a Google Workspace - subscription `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - async def sample_update_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - subscription = events_subscriptions_v1.Subscription() - subscription.target_resource = "target_resource_value" - subscription.event_types = ['event_types_value1', 'event_types_value2'] - subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" - - request = events_subscriptions_v1.UpdateSubscriptionRequest( - subscription=subscription, - ) - - # Make the request - operation = client.update_subscription(request=request) - - print("Waiting for operation to complete...") - - response = (await operation).result() - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.apps.events_subscriptions_v1.types.UpdateSubscriptionRequest, dict]]): - The request object. The request message for - [SubscriptionsService.UpdateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription]. - subscription (:class:`google.apps.events_subscriptions_v1.types.Subscription`): - Required. The subscription to update. - - The subscription's ``name`` field is used to identify - the subscription to update. - - This corresponds to the ``subscription`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): - Optional. Required. The field to update. - - You can update one of the following fields in a - subscription: - - - [``expire_time``][google.apps.events.subscriptions.v1.Subscription.expire_time]: - The timestamp when the subscription expires. - - [``ttl``][google.apps.events.subscriptions.v1.Subscription.ttl]: - The time-to-live (TTL) or duration of the - subscription. - - This corresponds to the ``update_mask`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.api_core.operation_async.AsyncOperation: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn - more about subscriptions, see the [Google Workspace - Events API - overview](\ https://developers.google.com/workspace/events/guides). - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([subscription, update_mask]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - request = subscriptions_service.UpdateSubscriptionRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if subscription is not None: - request.subscription = subscription - if update_mask is not None: - request.update_mask = update_mask - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.update_subscription, - default_timeout=60.0, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("subscription.name", request.subscription.name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - subscription_resource.Subscription, - metadata_type=subscriptions_service.UpdateSubscriptionMetadata, - ) - - # Done; return the response. - return response - - async def reactivate_subscription( - self, - request: Optional[ - Union[subscriptions_service.ReactivateSubscriptionRequest, dict] - ] = None, - *, - name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation_async.AsyncOperation: - r"""Reactivates a suspended Google Workspace subscription. - - This method resets your subscription's ``State`` field to - ``ACTIVE``. Before you use this method, you must fix the error - that suspended the subscription. To learn how to use this - method, see `Reactivate a Google Workspace - subscription `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - async def sample_reactivate_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.ReactivateSubscriptionRequest( - name="name_value", - ) - - # Make the request - operation = client.reactivate_subscription(request=request) - - print("Waiting for operation to complete...") - - response = (await operation).result() - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.apps.events_subscriptions_v1.types.ReactivateSubscriptionRequest, dict]]): - The request object. The request message for - [SubscriptionsService.ReactivateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription]. - name (:class:`str`): - Required. Resource name of the subscription. - - Format: ``subscriptions/{subscription}`` - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.api_core.operation_async.AsyncOperation: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn - more about subscriptions, see the [Google Workspace - Events API - overview](\ https://developers.google.com/workspace/events/guides). - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - request = subscriptions_service.ReactivateSubscriptionRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.reactivate_subscription, - default_timeout=60.0, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - subscription_resource.Subscription, - metadata_type=subscriptions_service.ReactivateSubscriptionMetadata, - ) - - # Done; return the response. - return response - - async def get_operation( - self, - request: Optional[operations_pb2.GetOperationRequest] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operations_pb2.Operation: - r"""Gets the latest state of a long-running operation. - - Args: - request (:class:`~.operations_pb2.GetOperationRequest`): - The request object. Request message for - `GetOperation` method. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - Returns: - ~.operations_pb2.Operation: - An ``Operation`` object. - """ - # 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): - request = operations_pb2.GetOperationRequest(**request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.get_operation, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "SubscriptionsServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - - -__all__ = ("SubscriptionsServiceAsyncClient",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/client.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/client.py deleted file mode 100644 index 4e4038f8a8f0..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/client.py +++ /dev/null @@ -1,1609 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from collections import OrderedDict -import os -import re -from typing import ( - Dict, - Mapping, - MutableMapping, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.oauth2 import service_account # type: ignore - -from google.apps.events_subscriptions_v1 import gapic_version as package_version - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.longrunning import operations_pb2 # type: ignore -from google.protobuf import duration_pb2 # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore - -from google.apps.events_subscriptions_v1.services.subscriptions_service import pagers -from google.apps.events_subscriptions_v1.types import ( - subscription_resource, - subscriptions_service, -) - -from .transports.base import DEFAULT_CLIENT_INFO, SubscriptionsServiceTransport -from .transports.grpc import SubscriptionsServiceGrpcTransport -from .transports.grpc_asyncio import SubscriptionsServiceGrpcAsyncIOTransport -from .transports.rest import SubscriptionsServiceRestTransport - - -class SubscriptionsServiceClientMeta(type): - """Metaclass for the SubscriptionsService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[SubscriptionsServiceTransport]] - _transport_registry["grpc"] = SubscriptionsServiceGrpcTransport - _transport_registry["grpc_asyncio"] = SubscriptionsServiceGrpcAsyncIOTransport - _transport_registry["rest"] = SubscriptionsServiceRestTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[SubscriptionsServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class SubscriptionsServiceClient(metaclass=SubscriptionsServiceClientMeta): - """A service that manages subscriptions to Google Workspace - events. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "workspaceevents.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "workspaceevents.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @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: - SubscriptionsServiceClient: 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 - 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: - SubscriptionsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file(filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> SubscriptionsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SubscriptionsServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def subscription_path( - subscription: str, - ) -> str: - """Returns a fully-qualified subscription string.""" - return "subscriptions/{subscription}".format( - subscription=subscription, - ) - - @staticmethod - def parse_subscription_path(path: str) -> Dict[str, str]: - """Parses a subscription path into its component segments.""" - m = re.match(r"^subscriptions/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def topic_path( - project: str, - topic: str, - ) -> str: - """Returns a fully-qualified topic string.""" - return "projects/{project}/topics/{topic}".format( - project=project, - topic=topic, - ) - - @staticmethod - def parse_topic_path(path: str) -> Dict[str, str]: - """Parses a topic path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/topics/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def user_path( - user: str, - ) -> str: - """Returns a fully-qualified user string.""" - return "users/{user}".format( - user=user, - ) - - @staticmethod - def parse_user_path(path: str) -> Dict[str, str]: - """Parses a user path into its component segments.""" - m = re.match(r"^users/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = SubscriptionsServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = SubscriptionsServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], universe_domain_env: Optional[str] - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = SubscriptionsServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - @staticmethod - def _compare_universes( - client_universe: str, credentials: ga_credentials.Credentials - ) -> bool: - """Returns True iff the universe domains used by the client and credentials match. - - Args: - client_universe (str): The universe domain configured via the client options. - credentials (ga_credentials.Credentials): The credentials being used in the client. - - Returns: - bool: True iff client_universe matches the universe in credentials. - - Raises: - ValueError: when client_universe does not match the universe in credentials. - """ - - default_universe = SubscriptionsServiceClient._DEFAULT_UNIVERSE - credentials_universe = getattr(credentials, "universe_domain", default_universe) - - if client_universe != credentials_universe: - raise ValueError( - "The configured universe domain " - f"({client_universe}) does not match the universe domain " - f"found in the credentials ({credentials_universe}). " - "If you haven't configured the universe domain explicitly, " - f"`{default_universe}` is the default." - ) - return True - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - self._is_universe_domain_valid = ( - self._is_universe_domain_valid - or SubscriptionsServiceClient._compare_universes( - self.universe_domain, self.transport._credentials - ) - ) - return self._is_universe_domain_valid - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[Union[str, SubscriptionsServiceTransport]] = None, - client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the subscriptions service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - 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, SubscriptionsServiceTransport]): The - transport to use. If set to None, a transport is chosen - automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - 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: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict(self._client_options) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr(self._client_options, "universe_domain", None) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = SubscriptionsServiceClient._read_environment_variables() - self._client_cert_source = SubscriptionsServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = SubscriptionsServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # Initialize the universe domain validation. - self._is_universe_domain_valid = False - - api_key_value = getattr(self._client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, SubscriptionsServiceTransport) - if transport_provided: - # transport is a SubscriptionsServiceTransport instance. - if credentials or self._client_options.credentials_file or api_key_value: - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(SubscriptionsServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or SubscriptionsServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - Transport = type(self).get_transport_class(cast(str, transport)) - self._transport = Transport( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - ) - - def create_subscription( - self, - request: Optional[ - Union[subscriptions_service.CreateSubscriptionRequest, dict] - ] = None, - *, - subscription: Optional[subscription_resource.Subscription] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Creates a Google Workspace subscription. To learn how to use - this method, see `Create a Google Workspace - subscription `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - def sample_create_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - subscription = events_subscriptions_v1.Subscription() - subscription.target_resource = "target_resource_value" - subscription.event_types = ['event_types_value1', 'event_types_value2'] - subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" - - request = events_subscriptions_v1.CreateSubscriptionRequest( - subscription=subscription, - ) - - # Make the request - operation = client.create_subscription(request=request) - - print("Waiting for operation to complete...") - - response = operation.result() - - # Handle the response - print(response) - - Args: - request (Union[google.apps.events_subscriptions_v1.types.CreateSubscriptionRequest, dict]): - The request object. The request message for - [SubscriptionsService.CreateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription]. - subscription (google.apps.events_subscriptions_v1.types.Subscription): - Required. The subscription resource - to create. - - This corresponds to the ``subscription`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.api_core.operation.Operation: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn - more about subscriptions, see the [Google Workspace - Events API - overview](\ https://developers.google.com/workspace/events/guides). - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([subscription]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # Minor optimization to avoid making a copy if the user passes - # in a subscriptions_service.CreateSubscriptionRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, subscriptions_service.CreateSubscriptionRequest): - request = subscriptions_service.CreateSubscriptionRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if subscription is not None: - request.subscription = subscription - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.create_subscription] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - subscription_resource.Subscription, - metadata_type=subscriptions_service.CreateSubscriptionMetadata, - ) - - # Done; return the response. - return response - - def delete_subscription( - self, - request: Optional[ - Union[subscriptions_service.DeleteSubscriptionRequest, dict] - ] = None, - *, - name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Deletes a Google Workspace subscription. To learn how to use - this method, see `Delete a Google Workspace - subscription `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - def sample_delete_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.DeleteSubscriptionRequest( - name="name_value", - ) - - # Make the request - operation = client.delete_subscription(request=request) - - print("Waiting for operation to complete...") - - response = operation.result() - - # Handle the response - print(response) - - Args: - request (Union[google.apps.events_subscriptions_v1.types.DeleteSubscriptionRequest, dict]): - The request object. The request message for - [SubscriptionsService.DeleteSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription]. - name (str): - Required. Resource name of the subscription to delete. - - Format: ``subscriptions/{subscription}`` - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.api_core.operation.Operation: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # Minor optimization to avoid making a copy if the user passes - # in a subscriptions_service.DeleteSubscriptionRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, subscriptions_service.DeleteSubscriptionRequest): - request = subscriptions_service.DeleteSubscriptionRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.delete_subscription] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - empty_pb2.Empty, - metadata_type=subscriptions_service.DeleteSubscriptionMetadata, - ) - - # Done; return the response. - return response - - def get_subscription( - self, - request: Optional[ - Union[subscriptions_service.GetSubscriptionRequest, dict] - ] = None, - *, - name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> subscription_resource.Subscription: - r"""Gets details about a Google Workspace subscription. To learn how - to use this method, see `Get details about a Google Workspace - subscription `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - def sample_get_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.GetSubscriptionRequest( - name="name_value", - ) - - # Make the request - response = client.get_subscription(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.apps.events_subscriptions_v1.types.GetSubscriptionRequest, dict]): - The request object. The request message for - [SubscriptionsService.GetSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription]. - name (str): - Required. Resource name of the subscription. - - Format: ``subscriptions/{subscription}`` - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.apps.events_subscriptions_v1.types.Subscription: - A subscription to receive events about a Google Workspace resource. To learn - more about subscriptions, see the [Google Workspace - Events API - overview](\ https://developers.google.com/workspace/events/guides). - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # Minor optimization to avoid making a copy if the user passes - # in a subscriptions_service.GetSubscriptionRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, subscriptions_service.GetSubscriptionRequest): - request = subscriptions_service.GetSubscriptionRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.get_subscription] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_subscriptions( - self, - request: Optional[ - Union[subscriptions_service.ListSubscriptionsRequest, dict] - ] = None, - *, - page_size: Optional[int] = None, - page_token: Optional[str] = None, - filter: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListSubscriptionsPager: - r"""Lists Google Workspace subscriptions. To learn how to use this - method, see `List Google Workspace - subscriptions `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - def sample_list_subscriptions(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.ListSubscriptionsRequest( - filter="filter_value", - ) - - # Make the request - page_result = client.list_subscriptions(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest, dict]): - The request object. The request message for - [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. - page_size (int): - Optional. The maximum number of subscriptions to return. - The service might return fewer than this value. - - If unspecified or set to ``0``, up to 50 subscriptions - are returned. - - The maximum value is 100. If you specify a value more - than 100, the system only returns 100 subscriptions. - - This corresponds to the ``page_size`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - page_token (str): - Optional. A page token, received from - a previous list subscriptions call. - Provide this parameter to retrieve the - subsequent page. - - When paginating, the filter value should - match the call that provided the page - token. Passing a different value might - lead to unexpected results. - - This corresponds to the ``page_token`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - filter (str): - Required. A query filter. - - You can filter subscriptions by event type - (``event_types``) and target resource - (``target_resource``). - - You must specify at least one event type in your query. - To filter for multiple event types, use the ``OR`` - operator. - - To filter by both event type and target resource, use - the ``AND`` operator and specify the full resource name, - such as ``//chat.googleapis.com/spaces/{space}``. - - For example, the following queries are valid: - - :: - - event_types:"google.workspace.chat.membership.v1.updated" OR - event_types:"google.workspace.chat.message.v1.created" - - event_types:"google.workspace.chat.message.v1.created" AND - target_resource="//chat.googleapis.com/spaces/{space}" - - ( event_types:"google.workspace.chat.membership.v1.updated" OR - event_types:"google.workspace.chat.message.v1.created" ) AND - target_resource="//chat.googleapis.com/spaces/{space}" - - The server rejects invalid queries with an - ``INVALID_ARGUMENT`` error. - - This corresponds to the ``filter`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.apps.events_subscriptions_v1.services.subscriptions_service.pagers.ListSubscriptionsPager: - The response message for - [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([page_size, page_token, filter]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # Minor optimization to avoid making a copy if the user passes - # in a subscriptions_service.ListSubscriptionsRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, subscriptions_service.ListSubscriptionsRequest): - request = subscriptions_service.ListSubscriptionsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if page_size is not None: - request.page_size = page_size - if page_token is not None: - request.page_token = page_token - if filter is not None: - request.filter = filter - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_subscriptions] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListSubscriptionsPager( - method=rpc, - request=request, - response=response, - metadata=metadata, - ) - - # Done; return the response. - return response - - def update_subscription( - self, - request: Optional[ - Union[subscriptions_service.UpdateSubscriptionRequest, dict] - ] = None, - *, - subscription: Optional[subscription_resource.Subscription] = None, - update_mask: Optional[field_mask_pb2.FieldMask] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Updates or renews a Google Workspace subscription. To learn how - to use this method, see `Update or renew a Google Workspace - subscription `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - def sample_update_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - subscription = events_subscriptions_v1.Subscription() - subscription.target_resource = "target_resource_value" - subscription.event_types = ['event_types_value1', 'event_types_value2'] - subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" - - request = events_subscriptions_v1.UpdateSubscriptionRequest( - subscription=subscription, - ) - - # Make the request - operation = client.update_subscription(request=request) - - print("Waiting for operation to complete...") - - response = operation.result() - - # Handle the response - print(response) - - Args: - request (Union[google.apps.events_subscriptions_v1.types.UpdateSubscriptionRequest, dict]): - The request object. The request message for - [SubscriptionsService.UpdateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription]. - subscription (google.apps.events_subscriptions_v1.types.Subscription): - Required. The subscription to update. - - The subscription's ``name`` field is used to identify - the subscription to update. - - This corresponds to the ``subscription`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - Optional. Required. The field to update. - - You can update one of the following fields in a - subscription: - - - [``expire_time``][google.apps.events.subscriptions.v1.Subscription.expire_time]: - The timestamp when the subscription expires. - - [``ttl``][google.apps.events.subscriptions.v1.Subscription.ttl]: - The time-to-live (TTL) or duration of the - subscription. - - This corresponds to the ``update_mask`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.api_core.operation.Operation: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn - more about subscriptions, see the [Google Workspace - Events API - overview](\ https://developers.google.com/workspace/events/guides). - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([subscription, update_mask]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # Minor optimization to avoid making a copy if the user passes - # in a subscriptions_service.UpdateSubscriptionRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, subscriptions_service.UpdateSubscriptionRequest): - request = subscriptions_service.UpdateSubscriptionRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if subscription is not None: - request.subscription = subscription - if update_mask is not None: - request.update_mask = update_mask - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.update_subscription] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("subscription.name", request.subscription.name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - subscription_resource.Subscription, - metadata_type=subscriptions_service.UpdateSubscriptionMetadata, - ) - - # Done; return the response. - return response - - def reactivate_subscription( - self, - request: Optional[ - Union[subscriptions_service.ReactivateSubscriptionRequest, dict] - ] = None, - *, - name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operation.Operation: - r"""Reactivates a suspended Google Workspace subscription. - - This method resets your subscription's ``State`` field to - ``ACTIVE``. Before you use this method, you must fix the error - that suspended the subscription. To learn how to use this - method, see `Reactivate a Google Workspace - subscription `__. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.apps import events_subscriptions_v1 - - def sample_reactivate_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.ReactivateSubscriptionRequest( - name="name_value", - ) - - # Make the request - operation = client.reactivate_subscription(request=request) - - print("Waiting for operation to complete...") - - response = operation.result() - - # Handle the response - print(response) - - Args: - request (Union[google.apps.events_subscriptions_v1.types.ReactivateSubscriptionRequest, dict]): - The request object. The request message for - [SubscriptionsService.ReactivateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription]. - name (str): - Required. Resource name of the subscription. - - Format: ``subscriptions/{subscription}`` - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.api_core.operation.Operation: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.apps.events_subscriptions_v1.types.Subscription` A subscription to receive events about a Google Workspace resource. To learn - more about subscriptions, see the [Google Workspace - Events API - overview](\ https://developers.google.com/workspace/events/guides). - - """ - # Create or coerce a protobuf request object. - # Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name]) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # Minor optimization to avoid making a copy if the user passes - # in a subscriptions_service.ReactivateSubscriptionRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, subscriptions_service.ReactivateSubscriptionRequest): - request = subscriptions_service.ReactivateSubscriptionRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.reactivate_subscription] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - subscription_resource.Subscription, - metadata_type=subscriptions_service.ReactivateSubscriptionMetadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "SubscriptionsServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - def get_operation( - self, - request: Optional[operations_pb2.GetOperationRequest] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operations_pb2.Operation: - r"""Gets the latest state of a long-running operation. - - Args: - request (:class:`~.operations_pb2.GetOperationRequest`): - The request object. Request message for - `GetOperation` method. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - Returns: - ~.operations_pb2.Operation: - An ``Operation`` object. - """ - # 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): - request = operations_pb2.GetOperationRequest(**request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method.wrap_method( - self._transport.get_operation, - default_timeout=None, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - - -__all__ = ("SubscriptionsServiceClient",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/pagers.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/pagers.py deleted file mode 100644 index 8832aa78df23..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/pagers.py +++ /dev/null @@ -1,162 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from typing import ( - Any, - AsyncIterator, - Awaitable, - Callable, - Iterator, - Optional, - Sequence, - Tuple, -) - -from google.apps.events_subscriptions_v1.types import ( - subscription_resource, - subscriptions_service, -) - - -class ListSubscriptionsPager: - """A pager for iterating through ``list_subscriptions`` requests. - - This class thinly wraps an initial - :class:`google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``subscriptions`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListSubscriptions`` requests and continue to iterate - through the ``subscriptions`` field on the - corresponding responses. - - All the usual :class:`google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[..., subscriptions_service.ListSubscriptionsResponse], - request: subscriptions_service.ListSubscriptionsRequest, - response: subscriptions_service.ListSubscriptionsResponse, - *, - metadata: Sequence[Tuple[str, str]] = () - ): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest): - The initial request object. - response (google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse): - The initial response object. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = subscriptions_service.ListSubscriptionsRequest(request) - self._response = response - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[subscriptions_service.ListSubscriptionsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method(self._request, metadata=self._metadata) - yield self._response - - def __iter__(self) -> Iterator[subscription_resource.Subscription]: - for page in self.pages: - yield from page.subscriptions - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) - - -class ListSubscriptionsAsyncPager: - """A pager for iterating through ``list_subscriptions`` requests. - - This class thinly wraps an initial - :class:`google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``subscriptions`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListSubscriptions`` requests and continue to iterate - through the ``subscriptions`` field on the - corresponding responses. - - All the usual :class:`google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., Awaitable[subscriptions_service.ListSubscriptionsResponse] - ], - request: subscriptions_service.ListSubscriptionsRequest, - response: subscriptions_service.ListSubscriptionsResponse, - *, - metadata: Sequence[Tuple[str, str]] = () - ): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest): - The initial request object. - response (google.apps.events_subscriptions_v1.types.ListSubscriptionsResponse): - The initial response object. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = subscriptions_service.ListSubscriptionsRequest(request) - self._response = response - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages( - self, - ) -> AsyncIterator[subscriptions_service.ListSubscriptionsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method(self._request, metadata=self._metadata) - yield self._response - - def __aiter__(self) -> AsyncIterator[subscription_resource.Subscription]: - async def async_generator(): - async for page in self.pages: - for response in page.subscriptions: - yield response - - return async_generator() - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/__init__.py deleted file mode 100644 index ad7767d7f900..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from collections import OrderedDict -from typing import Dict, Type - -from .base import SubscriptionsServiceTransport -from .grpc import SubscriptionsServiceGrpcTransport -from .grpc_asyncio import SubscriptionsServiceGrpcAsyncIOTransport -from .rest import SubscriptionsServiceRestInterceptor, SubscriptionsServiceRestTransport - -# Compile a registry of transports. -_transport_registry = ( - OrderedDict() -) # type: Dict[str, Type[SubscriptionsServiceTransport]] -_transport_registry["grpc"] = SubscriptionsServiceGrpcTransport -_transport_registry["grpc_asyncio"] = SubscriptionsServiceGrpcAsyncIOTransport -_transport_registry["rest"] = SubscriptionsServiceRestTransport - -__all__ = ( - "SubscriptionsServiceTransport", - "SubscriptionsServiceGrpcTransport", - "SubscriptionsServiceGrpcAsyncIOTransport", - "SubscriptionsServiceRestTransport", - "SubscriptionsServiceRestInterceptor", -) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/base.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/base.py deleted file mode 100644 index a2c6e1432124..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/base.py +++ /dev/null @@ -1,283 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -import abc -from typing import Awaitable, Callable, Dict, Optional, Sequence, Union - -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1, operations_v1 -from google.api_core import retry as retries -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.longrunning import operations_pb2 # type: ignore -from google.oauth2 import service_account # type: ignore - -from google.apps.events_subscriptions_v1 import gapic_version as package_version -from google.apps.events_subscriptions_v1.types import ( - subscription_resource, - subscriptions_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - - -class SubscriptionsServiceTransport(abc.ABC): - """Abstract transport class for SubscriptionsService.""" - - AUTH_SCOPES = ( - "https://www.googleapis.com/auth/chat.bot", - "https://www.googleapis.com/auth/chat.memberships", - "https://www.googleapis.com/auth/chat.memberships.readonly", - "https://www.googleapis.com/auth/chat.messages", - "https://www.googleapis.com/auth/chat.messages.reactions", - "https://www.googleapis.com/auth/chat.messages.reactions.readonly", - "https://www.googleapis.com/auth/chat.messages.readonly", - "https://www.googleapis.com/auth/chat.spaces", - "https://www.googleapis.com/auth/chat.spaces.readonly", - "https://www.googleapis.com/auth/meetings.space.created", - "https://www.googleapis.com/auth/meetings.space.readonly", - ) - - DEFAULT_HOST: str = "workspaceevents.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'workspaceevents.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (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 - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, **scopes_kwargs, quota_project_id=quota_project_id - ) - elif credentials is None: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr(service_account.Credentials, "with_always_use_jwt_access") - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.create_subscription: gapic_v1.method.wrap_method( - self.create_subscription, - default_timeout=60.0, - client_info=client_info, - ), - self.delete_subscription: gapic_v1.method.wrap_method( - self.delete_subscription, - default_timeout=60.0, - client_info=client_info, - ), - self.get_subscription: gapic_v1.method.wrap_method( - self.get_subscription, - default_retry=retries.Retry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.list_subscriptions: gapic_v1.method.wrap_method( - self.list_subscriptions, - default_retry=retries.Retry( - initial=1.0, - maximum=10.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.ServiceUnavailable, - ), - deadline=60.0, - ), - default_timeout=60.0, - client_info=client_info, - ), - self.update_subscription: gapic_v1.method.wrap_method( - self.update_subscription, - default_timeout=60.0, - client_info=client_info, - ), - self.reactivate_subscription: gapic_v1.method.wrap_method( - self.reactivate_subscription, - default_timeout=60.0, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def operations_client(self): - """Return the client designed to process long-running operations.""" - raise NotImplementedError() - - @property - def create_subscription( - self, - ) -> Callable[ - [subscriptions_service.CreateSubscriptionRequest], - Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], - ]: - raise NotImplementedError() - - @property - def delete_subscription( - self, - ) -> Callable[ - [subscriptions_service.DeleteSubscriptionRequest], - Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], - ]: - raise NotImplementedError() - - @property - def get_subscription( - self, - ) -> Callable[ - [subscriptions_service.GetSubscriptionRequest], - Union[ - subscription_resource.Subscription, - Awaitable[subscription_resource.Subscription], - ], - ]: - raise NotImplementedError() - - @property - def list_subscriptions( - self, - ) -> Callable[ - [subscriptions_service.ListSubscriptionsRequest], - Union[ - subscriptions_service.ListSubscriptionsResponse, - Awaitable[subscriptions_service.ListSubscriptionsResponse], - ], - ]: - raise NotImplementedError() - - @property - def update_subscription( - self, - ) -> Callable[ - [subscriptions_service.UpdateSubscriptionRequest], - Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], - ]: - raise NotImplementedError() - - @property - def reactivate_subscription( - self, - ) -> Callable[ - [subscriptions_service.ReactivateSubscriptionRequest], - Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], - ]: - raise NotImplementedError() - - @property - def get_operation( - self, - ) -> Callable[ - [operations_pb2.GetOperationRequest], - Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("SubscriptionsServiceTransport",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc.py deleted file mode 100644 index b0d457684884..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc.py +++ /dev/null @@ -1,462 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from typing import Callable, Dict, Optional, Sequence, Tuple, Union -import warnings - -from google.api_core import gapic_v1, grpc_helpers, operations_v1 -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.longrunning import operations_pb2 # type: ignore -import grpc # type: ignore - -from google.apps.events_subscriptions_v1.types import ( - subscription_resource, - subscriptions_service, -) - -from .base import DEFAULT_CLIENT_INFO, SubscriptionsServiceTransport - - -class SubscriptionsServiceGrpcTransport(SubscriptionsServiceTransport): - """gRPC backend transport for SubscriptionsService. - - A service that manages subscriptions to Google Workspace - events. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "workspaceevents.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[grpc.Channel] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'workspaceevents.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - channel (Optional[grpc.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the 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 a 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 - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - 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] = {} - self._operations_client: Optional[operations_v1.OperationsClient] = None - - 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: - # 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 - - 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 - - else: - 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 - ) - - # 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, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @classmethod - def create_channel( - cls, - host: str = "workspaceevents.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - 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 - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # Quick check: Only create a new client if we do not already have one. - if self._operations_client is None: - self._operations_client = operations_v1.OperationsClient(self.grpc_channel) - - # Return the client from cache. - return self._operations_client - - @property - def create_subscription( - self, - ) -> Callable[ - [subscriptions_service.CreateSubscriptionRequest], operations_pb2.Operation - ]: - r"""Return a callable for the create subscription method over gRPC. - - Creates a Google Workspace subscription. To learn how to use - this method, see `Create a Google Workspace - subscription `__. - - Returns: - Callable[[~.CreateSubscriptionRequest], - ~.Operation]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_subscription" not in self._stubs: - self._stubs["create_subscription"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/CreateSubscription", - request_serializer=subscriptions_service.CreateSubscriptionRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["create_subscription"] - - @property - def delete_subscription( - self, - ) -> Callable[ - [subscriptions_service.DeleteSubscriptionRequest], operations_pb2.Operation - ]: - r"""Return a callable for the delete subscription method over gRPC. - - Deletes a Google Workspace subscription. To learn how to use - this method, see `Delete a Google Workspace - subscription `__. - - Returns: - Callable[[~.DeleteSubscriptionRequest], - ~.Operation]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "delete_subscription" not in self._stubs: - self._stubs["delete_subscription"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/DeleteSubscription", - request_serializer=subscriptions_service.DeleteSubscriptionRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["delete_subscription"] - - @property - def get_subscription( - self, - ) -> Callable[ - [subscriptions_service.GetSubscriptionRequest], - subscription_resource.Subscription, - ]: - r"""Return a callable for the get subscription method over gRPC. - - Gets details about a Google Workspace subscription. To learn how - to use this method, see `Get details about a Google Workspace - subscription `__. - - Returns: - Callable[[~.GetSubscriptionRequest], - ~.Subscription]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_subscription" not in self._stubs: - self._stubs["get_subscription"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/GetSubscription", - request_serializer=subscriptions_service.GetSubscriptionRequest.serialize, - response_deserializer=subscription_resource.Subscription.deserialize, - ) - return self._stubs["get_subscription"] - - @property - def list_subscriptions( - self, - ) -> Callable[ - [subscriptions_service.ListSubscriptionsRequest], - subscriptions_service.ListSubscriptionsResponse, - ]: - r"""Return a callable for the list subscriptions method over gRPC. - - Lists Google Workspace subscriptions. To learn how to use this - method, see `List Google Workspace - subscriptions `__. - - Returns: - Callable[[~.ListSubscriptionsRequest], - ~.ListSubscriptionsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_subscriptions" not in self._stubs: - self._stubs["list_subscriptions"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/ListSubscriptions", - request_serializer=subscriptions_service.ListSubscriptionsRequest.serialize, - response_deserializer=subscriptions_service.ListSubscriptionsResponse.deserialize, - ) - return self._stubs["list_subscriptions"] - - @property - def update_subscription( - self, - ) -> Callable[ - [subscriptions_service.UpdateSubscriptionRequest], operations_pb2.Operation - ]: - r"""Return a callable for the update subscription method over gRPC. - - Updates or renews a Google Workspace subscription. To learn how - to use this method, see `Update or renew a Google Workspace - subscription `__. - - Returns: - Callable[[~.UpdateSubscriptionRequest], - ~.Operation]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "update_subscription" not in self._stubs: - self._stubs["update_subscription"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/UpdateSubscription", - request_serializer=subscriptions_service.UpdateSubscriptionRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["update_subscription"] - - @property - def reactivate_subscription( - self, - ) -> Callable[ - [subscriptions_service.ReactivateSubscriptionRequest], operations_pb2.Operation - ]: - r"""Return a callable for the reactivate subscription method over gRPC. - - Reactivates a suspended Google Workspace subscription. - - This method resets your subscription's ``State`` field to - ``ACTIVE``. Before you use this method, you must fix the error - that suspended the subscription. To learn how to use this - method, see `Reactivate a Google Workspace - subscription `__. - - Returns: - Callable[[~.ReactivateSubscriptionRequest], - ~.Operation]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "reactivate_subscription" not in self._stubs: - self._stubs["reactivate_subscription"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/ReactivateSubscription", - request_serializer=subscriptions_service.ReactivateSubscriptionRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["reactivate_subscription"] - - def close(self): - self.grpc_channel.close() - - @property - def get_operation( - self, - ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: - r"""Return a callable for the get_operation method over gRPC.""" - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_operation" not in self._stubs: - self._stubs["get_operation"] = self.grpc_channel.unary_unary( - "/google.longrunning.Operations/GetOperation", - request_serializer=operations_pb2.GetOperationRequest.SerializeToString, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["get_operation"] - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("SubscriptionsServiceGrpcTransport",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc_asyncio.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc_asyncio.py deleted file mode 100644 index 4ed43a674aef..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,467 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -import warnings - -from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.longrunning import operations_pb2 # type: ignore -import grpc # type: ignore -from grpc.experimental import aio # type: ignore - -from google.apps.events_subscriptions_v1.types import ( - subscription_resource, - subscriptions_service, -) - -from .base import DEFAULT_CLIENT_INFO, SubscriptionsServiceTransport -from .grpc import SubscriptionsServiceGrpcTransport - - -class SubscriptionsServiceGrpcAsyncIOTransport(SubscriptionsServiceTransport): - """gRPC AsyncIO backend transport for SubscriptionsService. - - A service that manages subscriptions to Google Workspace - events. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "workspaceevents.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - 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 - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "workspaceevents.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[aio.Channel] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'workspaceevents.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if ``channel`` is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[aio.Channel]): A ``Channel`` instance through - which to make calls. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the 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 a 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 - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - 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] = {} - self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None - - 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: - # 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 - 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 - - else: - 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 - ) - - # 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, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - self._grpc_channel = type(self).create_channel( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Wrap messages. This must be done after self._grpc_channel exists - self._prep_wrapped_messages(client_info) - - @property - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsAsyncClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # Quick check: Only create a new client if we do not already have one. - if self._operations_client is None: - self._operations_client = operations_v1.OperationsAsyncClient( - self.grpc_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def create_subscription( - self, - ) -> Callable[ - [subscriptions_service.CreateSubscriptionRequest], - Awaitable[operations_pb2.Operation], - ]: - r"""Return a callable for the create subscription method over gRPC. - - Creates a Google Workspace subscription. To learn how to use - this method, see `Create a Google Workspace - subscription `__. - - Returns: - Callable[[~.CreateSubscriptionRequest], - Awaitable[~.Operation]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_subscription" not in self._stubs: - self._stubs["create_subscription"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/CreateSubscription", - request_serializer=subscriptions_service.CreateSubscriptionRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["create_subscription"] - - @property - def delete_subscription( - self, - ) -> Callable[ - [subscriptions_service.DeleteSubscriptionRequest], - Awaitable[operations_pb2.Operation], - ]: - r"""Return a callable for the delete subscription method over gRPC. - - Deletes a Google Workspace subscription. To learn how to use - this method, see `Delete a Google Workspace - subscription `__. - - Returns: - Callable[[~.DeleteSubscriptionRequest], - Awaitable[~.Operation]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "delete_subscription" not in self._stubs: - self._stubs["delete_subscription"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/DeleteSubscription", - request_serializer=subscriptions_service.DeleteSubscriptionRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["delete_subscription"] - - @property - def get_subscription( - self, - ) -> Callable[ - [subscriptions_service.GetSubscriptionRequest], - Awaitable[subscription_resource.Subscription], - ]: - r"""Return a callable for the get subscription method over gRPC. - - Gets details about a Google Workspace subscription. To learn how - to use this method, see `Get details about a Google Workspace - subscription `__. - - Returns: - Callable[[~.GetSubscriptionRequest], - Awaitable[~.Subscription]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_subscription" not in self._stubs: - self._stubs["get_subscription"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/GetSubscription", - request_serializer=subscriptions_service.GetSubscriptionRequest.serialize, - response_deserializer=subscription_resource.Subscription.deserialize, - ) - return self._stubs["get_subscription"] - - @property - def list_subscriptions( - self, - ) -> Callable[ - [subscriptions_service.ListSubscriptionsRequest], - Awaitable[subscriptions_service.ListSubscriptionsResponse], - ]: - r"""Return a callable for the list subscriptions method over gRPC. - - Lists Google Workspace subscriptions. To learn how to use this - method, see `List Google Workspace - subscriptions `__. - - Returns: - Callable[[~.ListSubscriptionsRequest], - Awaitable[~.ListSubscriptionsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_subscriptions" not in self._stubs: - self._stubs["list_subscriptions"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/ListSubscriptions", - request_serializer=subscriptions_service.ListSubscriptionsRequest.serialize, - response_deserializer=subscriptions_service.ListSubscriptionsResponse.deserialize, - ) - return self._stubs["list_subscriptions"] - - @property - def update_subscription( - self, - ) -> Callable[ - [subscriptions_service.UpdateSubscriptionRequest], - Awaitable[operations_pb2.Operation], - ]: - r"""Return a callable for the update subscription method over gRPC. - - Updates or renews a Google Workspace subscription. To learn how - to use this method, see `Update or renew a Google Workspace - subscription `__. - - Returns: - Callable[[~.UpdateSubscriptionRequest], - Awaitable[~.Operation]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "update_subscription" not in self._stubs: - self._stubs["update_subscription"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/UpdateSubscription", - request_serializer=subscriptions_service.UpdateSubscriptionRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["update_subscription"] - - @property - def reactivate_subscription( - self, - ) -> Callable[ - [subscriptions_service.ReactivateSubscriptionRequest], - Awaitable[operations_pb2.Operation], - ]: - r"""Return a callable for the reactivate subscription method over gRPC. - - Reactivates a suspended Google Workspace subscription. - - This method resets your subscription's ``State`` field to - ``ACTIVE``. Before you use this method, you must fix the error - that suspended the subscription. To learn how to use this - method, see `Reactivate a Google Workspace - subscription `__. - - Returns: - Callable[[~.ReactivateSubscriptionRequest], - Awaitable[~.Operation]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "reactivate_subscription" not in self._stubs: - self._stubs["reactivate_subscription"] = self.grpc_channel.unary_unary( - "/google.apps.events.subscriptions.v1.SubscriptionsService/ReactivateSubscription", - request_serializer=subscriptions_service.ReactivateSubscriptionRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["reactivate_subscription"] - - def close(self): - return self.grpc_channel.close() - - @property - def get_operation( - self, - ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: - r"""Return a callable for the get_operation method over gRPC.""" - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_operation" not in self._stubs: - self._stubs["get_operation"] = self.grpc_channel.unary_unary( - "/google.longrunning.Operations/GetOperation", - request_serializer=operations_pb2.GetOperationRequest.SerializeToString, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["get_operation"] - - -__all__ = ("SubscriptionsServiceGrpcAsyncIOTransport",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/rest.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/rest.py deleted file mode 100644 index 488b03b2364e..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/services/subscriptions_service/transports/rest.py +++ /dev/null @@ -1,1132 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# - -import dataclasses -import json # type: ignore -import re -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union -import warnings - -from google.api_core import ( - gapic_v1, - operations_v1, - path_template, - rest_helpers, - rest_streaming, -) -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.transport.requests import AuthorizedSession # type: ignore -from google.protobuf import json_format -import grpc # type: ignore -from requests import __version__ as requests_version - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - - -from google.longrunning import operations_pb2 # type: ignore - -from google.apps.events_subscriptions_v1.types import ( - subscription_resource, - subscriptions_service, -) - -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO -from .base import SubscriptionsServiceTransport - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, - grpc_version=None, - rest_version=requests_version, -) - - -class SubscriptionsServiceRestInterceptor: - """Interceptor for SubscriptionsService. - - Interceptors are used to manipulate requests, request metadata, and responses - in arbitrary ways. - Example use cases include: - * Logging - * Verifying requests according to service or custom semantics - * Stripping extraneous information from responses - - These use cases and more can be enabled by injecting an - instance of a custom subclass when constructing the SubscriptionsServiceRestTransport. - - .. code-block:: python - class MyCustomSubscriptionsServiceInterceptor(SubscriptionsServiceRestInterceptor): - def pre_create_subscription(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_create_subscription(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_delete_subscription(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_delete_subscription(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_get_subscription(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_get_subscription(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_list_subscriptions(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_list_subscriptions(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_reactivate_subscription(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_reactivate_subscription(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_update_subscription(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_update_subscription(self, response): - logging.log(f"Received response: {response}") - return response - - transport = SubscriptionsServiceRestTransport(interceptor=MyCustomSubscriptionsServiceInterceptor()) - client = SubscriptionsServiceClient(transport=transport) - - - """ - - def pre_create_subscription( - self, - request: subscriptions_service.CreateSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[ - subscriptions_service.CreateSubscriptionRequest, Sequence[Tuple[str, str]] - ]: - """Pre-rpc interceptor for create_subscription - - Override in a subclass to manipulate the request or metadata - before they are sent to the SubscriptionsService server. - """ - return request, metadata - - def post_create_subscription( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for create_subscription - - Override in a subclass to manipulate the response - after it is returned by the SubscriptionsService server but before - it is returned to user code. - """ - return response - - def pre_delete_subscription( - self, - request: subscriptions_service.DeleteSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[ - subscriptions_service.DeleteSubscriptionRequest, Sequence[Tuple[str, str]] - ]: - """Pre-rpc interceptor for delete_subscription - - Override in a subclass to manipulate the request or metadata - before they are sent to the SubscriptionsService server. - """ - return request, metadata - - def post_delete_subscription( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for delete_subscription - - Override in a subclass to manipulate the response - after it is returned by the SubscriptionsService server but before - it is returned to user code. - """ - return response - - def pre_get_subscription( - self, - request: subscriptions_service.GetSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[subscriptions_service.GetSubscriptionRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for get_subscription - - Override in a subclass to manipulate the request or metadata - before they are sent to the SubscriptionsService server. - """ - return request, metadata - - def post_get_subscription( - self, response: subscription_resource.Subscription - ) -> subscription_resource.Subscription: - """Post-rpc interceptor for get_subscription - - Override in a subclass to manipulate the response - after it is returned by the SubscriptionsService server but before - it is returned to user code. - """ - return response - - def pre_list_subscriptions( - self, - request: subscriptions_service.ListSubscriptionsRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[ - subscriptions_service.ListSubscriptionsRequest, Sequence[Tuple[str, str]] - ]: - """Pre-rpc interceptor for list_subscriptions - - Override in a subclass to manipulate the request or metadata - before they are sent to the SubscriptionsService server. - """ - return request, metadata - - def post_list_subscriptions( - self, response: subscriptions_service.ListSubscriptionsResponse - ) -> subscriptions_service.ListSubscriptionsResponse: - """Post-rpc interceptor for list_subscriptions - - Override in a subclass to manipulate the response - after it is returned by the SubscriptionsService server but before - it is returned to user code. - """ - return response - - def pre_reactivate_subscription( - self, - request: subscriptions_service.ReactivateSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[ - subscriptions_service.ReactivateSubscriptionRequest, Sequence[Tuple[str, str]] - ]: - """Pre-rpc interceptor for reactivate_subscription - - Override in a subclass to manipulate the request or metadata - before they are sent to the SubscriptionsService server. - """ - return request, metadata - - def post_reactivate_subscription( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for reactivate_subscription - - Override in a subclass to manipulate the response - after it is returned by the SubscriptionsService server but before - it is returned to user code. - """ - return response - - def pre_update_subscription( - self, - request: subscriptions_service.UpdateSubscriptionRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[ - subscriptions_service.UpdateSubscriptionRequest, Sequence[Tuple[str, str]] - ]: - """Pre-rpc interceptor for update_subscription - - Override in a subclass to manipulate the request or metadata - before they are sent to the SubscriptionsService server. - """ - return request, metadata - - def post_update_subscription( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for update_subscription - - Override in a subclass to manipulate the response - after it is returned by the SubscriptionsService server but before - it is returned to user code. - """ - return response - - def pre_get_operation( - self, - request: operations_pb2.GetOperationRequest, - metadata: Sequence[Tuple[str, str]], - ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for get_operation - - Override in a subclass to manipulate the request or metadata - before they are sent to the SubscriptionsService server. - """ - return request, metadata - - def post_get_operation( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for get_operation - - Override in a subclass to manipulate the response - after it is returned by the SubscriptionsService server but before - it is returned to user code. - """ - return response - - -@dataclasses.dataclass -class SubscriptionsServiceRestStub: - _session: AuthorizedSession - _host: str - _interceptor: SubscriptionsServiceRestInterceptor - - -class SubscriptionsServiceRestTransport(SubscriptionsServiceTransport): - """REST backend transport for SubscriptionsService. - - A service that manages subscriptions to Google Workspace - events. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends JSON representations of protocol buffers over HTTP/1.1 - - """ - - def __init__( - self, - *, - host: str = "workspaceevents.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = "https", - interceptor: Optional[SubscriptionsServiceRestInterceptor] = None, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'workspaceevents.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client - certificate to configure mutual TLS HTTP channel. It is ignored - if ``channel`` 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 are developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - url_scheme: the protocol scheme for the API endpoint. Normally - "https", but for testing or local servers, - "http" can be specified. - """ - # Run the base constructor - # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. - # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the - # credentials object - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - self._session = AuthorizedSession( - self._credentials, default_host=self.DEFAULT_HOST - ) - self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None - if client_cert_source_for_mtls: - self._session.configure_mtls_channel(client_cert_source_for_mtls) - self._interceptor = interceptor or SubscriptionsServiceRestInterceptor() - self._prep_wrapped_messages(client_info) - - @property - def operations_client(self) -> operations_v1.AbstractOperationsClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # Only create a new client if we do not already have one. - if self._operations_client is None: - http_options: Dict[str, List[Dict[str, str]]] = { - "google.longrunning.Operations.GetOperation": [ - { - "method": "get", - "uri": "/v1/{name=operations/**}", - }, - ], - } - - rest_transport = operations_v1.OperationsRestTransport( - host=self._host, - # use the credentials which are saved - credentials=self._credentials, - scopes=self._scopes, - http_options=http_options, - path_prefix="v1", - ) - - self._operations_client = operations_v1.AbstractOperationsClient( - transport=rest_transport - ) - - # Return the client from cache. - return self._operations_client - - class _CreateSubscription(SubscriptionsServiceRestStub): - def __hash__(self): - return hash("CreateSubscription") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - def __call__( - self, - request: subscriptions_service.CreateSubscriptionRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operations_pb2.Operation: - r"""Call the create subscription method over HTTP. - - Args: - request (~.subscriptions_service.CreateSubscriptionRequest): - The request object. The request message for - [SubscriptionsService.CreateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. - - """ - - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/subscriptions", - "body": "subscription", - }, - ] - request, metadata = self._interceptor.pre_create_subscription( - request, metadata - ) - pb_request = subscriptions_service.CreateSubscriptionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True - ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] - - # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - - # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_create_subscription(resp) - return resp - - class _DeleteSubscription(SubscriptionsServiceRestStub): - def __hash__(self): - return hash("DeleteSubscription") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - def __call__( - self, - request: subscriptions_service.DeleteSubscriptionRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operations_pb2.Operation: - r"""Call the delete subscription method over HTTP. - - Args: - request (~.subscriptions_service.DeleteSubscriptionRequest): - The request object. The request message for - [SubscriptionsService.DeleteSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. - - """ - - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/v1/{name=subscriptions/*}", - }, - ] - request, metadata = self._interceptor.pre_delete_subscription( - request, metadata - ) - pb_request = subscriptions_service.DeleteSubscriptionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] - - # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - - # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_delete_subscription(resp) - return resp - - class _GetSubscription(SubscriptionsServiceRestStub): - def __hash__(self): - return hash("GetSubscription") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - def __call__( - self, - request: subscriptions_service.GetSubscriptionRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> subscription_resource.Subscription: - r"""Call the get subscription method over HTTP. - - Args: - request (~.subscriptions_service.GetSubscriptionRequest): - The request object. The request message for - [SubscriptionsService.GetSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.subscription_resource.Subscription: - A subscription to receive events about a Google - Workspace resource. To learn more about subscriptions, - see the `Google Workspace Events API - overview `__. - - """ - - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=subscriptions/*}", - }, - ] - request, metadata = self._interceptor.pre_get_subscription( - request, metadata - ) - pb_request = subscriptions_service.GetSubscriptionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] - - # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - - # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = subscription_resource.Subscription() - pb_resp = subscription_resource.Subscription.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_subscription(resp) - return resp - - class _ListSubscriptions(SubscriptionsServiceRestStub): - def __hash__(self): - return hash("ListSubscriptions") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "filter": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - def __call__( - self, - request: subscriptions_service.ListSubscriptionsRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> subscriptions_service.ListSubscriptionsResponse: - r"""Call the list subscriptions method over HTTP. - - Args: - request (~.subscriptions_service.ListSubscriptionsRequest): - The request object. The request message for - [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.subscriptions_service.ListSubscriptionsResponse: - The response message for - [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. - - """ - - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/subscriptions", - }, - ] - request, metadata = self._interceptor.pre_list_subscriptions( - request, metadata - ) - pb_request = subscriptions_service.ListSubscriptionsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] - - # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - - # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = subscriptions_service.ListSubscriptionsResponse() - pb_resp = subscriptions_service.ListSubscriptionsResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_subscriptions(resp) - return resp - - class _ReactivateSubscription(SubscriptionsServiceRestStub): - def __hash__(self): - return hash("ReactivateSubscription") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - def __call__( - self, - request: subscriptions_service.ReactivateSubscriptionRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operations_pb2.Operation: - r"""Call the reactivate subscription method over HTTP. - - Args: - request (~.subscriptions_service.ReactivateSubscriptionRequest): - The request object. The request message for - [SubscriptionsService.ReactivateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. - - """ - - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1/{name=subscriptions/*}:reactivate", - "body": "*", - }, - ] - request, metadata = self._interceptor.pre_reactivate_subscription( - request, metadata - ) - pb_request = subscriptions_service.ReactivateSubscriptionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True - ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] - - # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - - # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_reactivate_subscription(resp) - return resp - - class _UpdateSubscription(SubscriptionsServiceRestStub): - def __hash__(self): - return hash("UpdateSubscription") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - def __call__( - self, - request: subscriptions_service.UpdateSubscriptionRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operations_pb2.Operation: - r"""Call the update subscription method over HTTP. - - Args: - request (~.subscriptions_service.UpdateSubscriptionRequest): - The request object. The request message for - [SubscriptionsService.UpdateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. - - """ - - http_options: List[Dict[str, str]] = [ - { - "method": "patch", - "uri": "/v1/{subscription.name=subscriptions/*}", - "body": "subscription", - }, - ] - request, metadata = self._interceptor.pre_update_subscription( - request, metadata - ) - pb_request = subscriptions_service.UpdateSubscriptionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True - ) - uri = transcoded_request["uri"] - method = transcoded_request["method"] - - # Jsonify the query params - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update(self._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - - # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_update_subscription(resp) - return resp - - @property - def create_subscription( - self, - ) -> Callable[ - [subscriptions_service.CreateSubscriptionRequest], operations_pb2.Operation - ]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._CreateSubscription(self._session, self._host, self._interceptor) # type: ignore - - @property - def delete_subscription( - self, - ) -> Callable[ - [subscriptions_service.DeleteSubscriptionRequest], operations_pb2.Operation - ]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._DeleteSubscription(self._session, self._host, self._interceptor) # type: ignore - - @property - def get_subscription( - self, - ) -> Callable[ - [subscriptions_service.GetSubscriptionRequest], - subscription_resource.Subscription, - ]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._GetSubscription(self._session, self._host, self._interceptor) # type: ignore - - @property - def list_subscriptions( - self, - ) -> Callable[ - [subscriptions_service.ListSubscriptionsRequest], - subscriptions_service.ListSubscriptionsResponse, - ]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._ListSubscriptions(self._session, self._host, self._interceptor) # type: ignore - - @property - def reactivate_subscription( - self, - ) -> Callable[ - [subscriptions_service.ReactivateSubscriptionRequest], operations_pb2.Operation - ]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._ReactivateSubscription(self._session, self._host, self._interceptor) # type: ignore - - @property - def update_subscription( - self, - ) -> Callable[ - [subscriptions_service.UpdateSubscriptionRequest], operations_pb2.Operation - ]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._UpdateSubscription(self._session, self._host, self._interceptor) # type: ignore - - @property - def get_operation(self): - return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore - - class _GetOperation(SubscriptionsServiceRestStub): - def __call__( - self, - request: operations_pb2.GetOperationRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> operations_pb2.Operation: - r"""Call the get operation method over HTTP. - - Args: - request (operations_pb2.GetOperationRequest): - The request object for GetOperation method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - operations_pb2.Operation: Response from GetOperation method. - """ - - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1/{name=operations/**}", - }, - ] - - request, metadata = self._interceptor.pre_get_operation(request, metadata) - request_kwargs = json_format.MessageToDict(request) - transcoded_request = path_template.transcode(http_options, **request_kwargs) - - uri = transcoded_request["uri"] - method = transcoded_request["method"] - - # Jsonify the query params - query_params = json.loads(json.dumps(transcoded_request["query_params"])) - - # Send the request - headers = dict(metadata) - headers["Content-Type"] = "application/json" - - response = getattr(self._session, method)( - "{host}{uri}".format(host=self._host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params), - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - resp = operations_pb2.Operation() - resp = json_format.Parse(response.content.decode("utf-8"), resp) - resp = self._interceptor.post_get_operation(resp) - return resp - - @property - def kind(self) -> str: - return "rest" - - def close(self): - self._session.close() - - -__all__ = ("SubscriptionsServiceRestTransport",) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/__init__.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/__init__.py deleted file mode 100644 index ff5b123f73de..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/__init__.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from .subscription_resource import NotificationEndpoint, PayloadOptions, Subscription -from .subscriptions_service import ( - CreateSubscriptionMetadata, - CreateSubscriptionRequest, - DeleteSubscriptionMetadata, - DeleteSubscriptionRequest, - GetSubscriptionRequest, - ListSubscriptionsRequest, - ListSubscriptionsResponse, - ReactivateSubscriptionMetadata, - ReactivateSubscriptionRequest, - UpdateSubscriptionMetadata, - UpdateSubscriptionRequest, -) - -__all__ = ( - "NotificationEndpoint", - "PayloadOptions", - "Subscription", - "CreateSubscriptionMetadata", - "CreateSubscriptionRequest", - "DeleteSubscriptionMetadata", - "DeleteSubscriptionRequest", - "GetSubscriptionRequest", - "ListSubscriptionsRequest", - "ListSubscriptionsResponse", - "ReactivateSubscriptionMetadata", - "ReactivateSubscriptionRequest", - "UpdateSubscriptionMetadata", - "UpdateSubscriptionRequest", -) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscription_resource.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscription_resource.py deleted file mode 100644 index bebd284fa206..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscription_resource.py +++ /dev/null @@ -1,353 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from __future__ import annotations - -from typing import MutableMapping, MutableSequence - -from google.protobuf import duration_pb2 # type: ignore -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -import proto # type: ignore - -__protobuf__ = proto.module( - package="google.apps.events.subscriptions.v1", - manifest={ - "Subscription", - "PayloadOptions", - "NotificationEndpoint", - }, -) - - -class Subscription(proto.Message): - r"""A subscription to receive events about a Google Workspace resource. - To learn more about subscriptions, see the `Google Workspace Events - API - overview `__. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - expire_time (google.protobuf.timestamp_pb2.Timestamp): - Non-empty default. The timestamp in UTC when - the subscription expires. Always displayed on - output, regardless of what was used on input. - - This field is a member of `oneof`_ ``expiration``. - ttl (google.protobuf.duration_pb2.Duration): - Input only. The time-to-live (TTL) or duration for the - subscription. If unspecified or set to ``0``, uses the - maximum possible duration. - - This field is a member of `oneof`_ ``expiration``. - name (str): - Optional. Immutable. Identifier. Resource name of the - subscription. - - Format: ``subscriptions/{subscription}`` - uid (str): - Output only. System-assigned unique - identifier for the subscription. - target_resource (str): - Required. Immutable. The Google Workspace resource that's - monitored for events, formatted as the `full resource - name `__. To - learn about target resources, see `Supported Google - Workspace - resources `__. - - A user can only authorize your app to create one - subscription for a given target resource. If your app tries - to create another subscription with the same user - credentials, the request returns an ``ALREADY_EXISTS`` - error. - event_types (MutableSequence[str]): - Required. Immutable. Unordered list. Input for creating a - subscription. Otherwise, output only. One or more types of - events to receive about the target resource. Formatted - according to the CloudEvents specification. - - For a list of supported event types, see the following - documentation: - - - `Google Chat - events `__ - - `Google Meet - events `__ - - By default, you also receive events about the `lifecycle of - your - subscription `__. - You don't need to specify lifecycle events for this field. - - If you specify an event type that doesn't exist for the - target resource, the request returns an HTTP - ``400 Bad Request`` status code. - payload_options (google.apps.events_subscriptions_v1.types.PayloadOptions): - Optional. Options about what data to include - in the event payload. Only supported for Google - Chat events. - notification_endpoint (google.apps.events_subscriptions_v1.types.NotificationEndpoint): - Required. Immutable. The endpoint where the - subscription delivers events, such as a Pub/Sub - topic. - state (google.apps.events_subscriptions_v1.types.Subscription.State): - Output only. The state of the subscription. - Determines whether the subscription can receive - events and deliver them to the notification - endpoint. - suspension_reason (google.apps.events_subscriptions_v1.types.Subscription.ErrorType): - Output only. The error that suspended the subscription. - - To reactivate the subscription, resolve the error and call - the - [``ReactivateSubscription``][google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription] - method. - authority (str): - Output only. The user who authorized the creation of the - subscription. - - Format: ``users/{user}`` - - For Google Workspace users, the ``{user}`` value is the - ```user.id`` `__ - field from the Directory API. - create_time (google.protobuf.timestamp_pb2.Timestamp): - Output only. The time when the subscription - is created. - update_time (google.protobuf.timestamp_pb2.Timestamp): - Output only. The last time that the - subscription is updated. - reconciling (bool): - Output only. If ``true``, the subscription is in the process - of being updated. - etag (str): - Optional. This checksum is computed by the - server based on the value of other fields, and - might be sent on update requests to ensure the - client has an up-to-date value before - proceeding. - """ - - class State(proto.Enum): - r"""Possible states for the subscription. - - Values: - STATE_UNSPECIFIED (0): - Default value. This value is unused. - ACTIVE (1): - The subscription is active and can receive - and deliver events to its notification endpoint. - SUSPENDED (2): - The subscription is unable to receive events due to an - error. To identify the error, see the - [``suspension_reason``][google.apps.events.subscriptions.v1.Subscription.suspension_reason] - field. - DELETED (3): - The subscription is deleted. - """ - STATE_UNSPECIFIED = 0 - ACTIVE = 1 - SUSPENDED = 2 - DELETED = 3 - - class ErrorType(proto.Enum): - r"""Possible errors for a subscription. - - Values: - ERROR_TYPE_UNSPECIFIED (0): - Default value. This value is unused. - USER_SCOPE_REVOKED (1): - The authorizing user has revoked the grant of one or more - OAuth scopes. To learn more about authorization for Google - Workspace, see `Configure the OAuth consent - screen `__. - RESOURCE_DELETED (2): - The target resource for the subscription no - longer exists. - USER_AUTHORIZATION_FAILURE (3): - The user that authorized the creation of the - subscription no longer has access to the - subscription's target resource. - ENDPOINT_PERMISSION_DENIED (4): - The Google Workspace application doesn't have - access to deliver events to your subscription's - notification endpoint. - ENDPOINT_NOT_FOUND (6): - The subscription's notification endpoint - doesn't exist, or the endpoint can't be found in - the Google Cloud project where you created the - subscription. - ENDPOINT_RESOURCE_EXHAUSTED (7): - The subscription's notification endpoint - failed to receive events due to insufficient - quota or reaching rate limiting. - OTHER (5): - An unidentified error has occurred. - """ - ERROR_TYPE_UNSPECIFIED = 0 - USER_SCOPE_REVOKED = 1 - RESOURCE_DELETED = 2 - USER_AUTHORIZATION_FAILURE = 3 - ENDPOINT_PERMISSION_DENIED = 4 - ENDPOINT_NOT_FOUND = 6 - ENDPOINT_RESOURCE_EXHAUSTED = 7 - OTHER = 5 - - expire_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=13, - oneof="expiration", - message=timestamp_pb2.Timestamp, - ) - ttl: duration_pb2.Duration = proto.Field( - proto.MESSAGE, - number=14, - oneof="expiration", - message=duration_pb2.Duration, - ) - name: str = proto.Field( - proto.STRING, - number=1, - ) - uid: str = proto.Field( - proto.STRING, - number=2, - ) - target_resource: str = proto.Field( - proto.STRING, - number=4, - ) - event_types: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=5, - ) - payload_options: "PayloadOptions" = proto.Field( - proto.MESSAGE, - number=6, - message="PayloadOptions", - ) - notification_endpoint: "NotificationEndpoint" = proto.Field( - proto.MESSAGE, - number=7, - message="NotificationEndpoint", - ) - state: State = proto.Field( - proto.ENUM, - number=8, - enum=State, - ) - suspension_reason: ErrorType = proto.Field( - proto.ENUM, - number=18, - enum=ErrorType, - ) - authority: str = proto.Field( - proto.STRING, - number=10, - ) - create_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=11, - message=timestamp_pb2.Timestamp, - ) - update_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=12, - message=timestamp_pb2.Timestamp, - ) - reconciling: bool = proto.Field( - proto.BOOL, - number=15, - ) - etag: str = proto.Field( - proto.STRING, - number=17, - ) - - -class PayloadOptions(proto.Message): - r"""Options about what data to include in the event payload. Only - supported for Google Chat events. - - Attributes: - include_resource (bool): - Optional. Whether the event payload includes data about the - resource that changed. For example, for an event where a - Google Chat message was created, whether the payload - contains data about the - ```Message`` `__ - resource. If false, the event payload only includes the name - of the changed resource. - field_mask (google.protobuf.field_mask_pb2.FieldMask): - Optional. If ``include_resource`` is set to ``true``, the - list of fields to include in the event payload. Separate - fields with a comma. For example, to include a Google Chat - message's sender and create time, enter - ``message.sender,message.createTime``. If omitted, the - payload includes all fields for the resource. - - If you specify a field that doesn't exist for the resource, - the system ignores the field. - """ - - include_resource: bool = proto.Field( - proto.BOOL, - number=1, - ) - field_mask: field_mask_pb2.FieldMask = proto.Field( - proto.MESSAGE, - number=2, - message=field_mask_pb2.FieldMask, - ) - - -class NotificationEndpoint(proto.Message): - r"""The endpoint where the subscription delivers events. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - pubsub_topic (str): - Immutable. The Cloud Pub/Sub topic that receives events for - the subscription. - - Format: ``projects/{project}/topics/{topic}`` - - You must create the topic in the same Google Cloud project - where you create this subscription. - - When the topic receives events, the events are encoded as - Cloud Pub/Sub messages. For details, see the `Google Cloud - Pub/Sub Protocol Binding for - CloudEvents `__. - - This field is a member of `oneof`_ ``endpoint``. - """ - - pubsub_topic: str = proto.Field( - proto.STRING, - number=1, - oneof="endpoint", - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscriptions_service.py b/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscriptions_service.py deleted file mode 100644 index 4d6813fb0cf9..000000000000 --- a/packages/google-apps-events-subscriptions/google/apps/events_subscriptions_v1/types/subscriptions_service.py +++ /dev/null @@ -1,297 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -from __future__ import annotations - -from typing import MutableMapping, MutableSequence - -from google.protobuf import field_mask_pb2 # type: ignore -import proto # type: ignore - -from google.apps.events_subscriptions_v1.types import subscription_resource - -__protobuf__ = proto.module( - package="google.apps.events.subscriptions.v1", - manifest={ - "CreateSubscriptionRequest", - "DeleteSubscriptionRequest", - "GetSubscriptionRequest", - "UpdateSubscriptionRequest", - "ReactivateSubscriptionRequest", - "ListSubscriptionsRequest", - "ListSubscriptionsResponse", - "UpdateSubscriptionMetadata", - "CreateSubscriptionMetadata", - "DeleteSubscriptionMetadata", - "ReactivateSubscriptionMetadata", - }, -) - - -class CreateSubscriptionRequest(proto.Message): - r"""The request message for - [SubscriptionsService.CreateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription]. - - Attributes: - subscription (google.apps.events_subscriptions_v1.types.Subscription): - Required. The subscription resource to - create. - validate_only (bool): - Optional. If set to ``true``, validates and previews the - request, but doesn't create the subscription. - """ - - subscription: subscription_resource.Subscription = proto.Field( - proto.MESSAGE, - number=1, - message=subscription_resource.Subscription, - ) - validate_only: bool = proto.Field( - proto.BOOL, - number=2, - ) - - -class DeleteSubscriptionRequest(proto.Message): - r"""The request message for - [SubscriptionsService.DeleteSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription]. - - Attributes: - name (str): - Required. Resource name of the subscription to delete. - - Format: ``subscriptions/{subscription}`` - validate_only (bool): - Optional. If set to ``true``, validates and previews the - request, but doesn't delete the subscription. - allow_missing (bool): - Optional. If set to ``true`` and the subscription isn't - found, the request succeeds but doesn't delete the - subscription. - etag (str): - Optional. Etag of the subscription. - - If present, it must match with the server's etag. Otherwise, - request fails with the status ``ABORTED``. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - validate_only: bool = proto.Field( - proto.BOOL, - number=2, - ) - allow_missing: bool = proto.Field( - proto.BOOL, - number=3, - ) - etag: str = proto.Field( - proto.STRING, - number=4, - ) - - -class GetSubscriptionRequest(proto.Message): - r"""The request message for - [SubscriptionsService.GetSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription]. - - Attributes: - name (str): - Required. Resource name of the subscription. - - Format: ``subscriptions/{subscription}`` - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - - -class UpdateSubscriptionRequest(proto.Message): - r"""The request message for - [SubscriptionsService.UpdateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription]. - - Attributes: - subscription (google.apps.events_subscriptions_v1.types.Subscription): - Required. The subscription to update. - - The subscription's ``name`` field is used to identify the - subscription to update. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - Optional. Required. The field to update. - - You can update one of the following fields in a - subscription: - - - [``expire_time``][google.apps.events.subscriptions.v1.Subscription.expire_time]: - The timestamp when the subscription expires. - - [``ttl``][google.apps.events.subscriptions.v1.Subscription.ttl]: - The time-to-live (TTL) or duration of the subscription. - validate_only (bool): - Optional. If set to ``true``, validates and previews the - request, but doesn't update the subscription. - """ - - subscription: subscription_resource.Subscription = proto.Field( - proto.MESSAGE, - number=1, - message=subscription_resource.Subscription, - ) - update_mask: field_mask_pb2.FieldMask = proto.Field( - proto.MESSAGE, - number=2, - message=field_mask_pb2.FieldMask, - ) - validate_only: bool = proto.Field( - proto.BOOL, - number=3, - ) - - -class ReactivateSubscriptionRequest(proto.Message): - r"""The request message for - [SubscriptionsService.ReactivateSubscription][google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription]. - - Attributes: - name (str): - Required. Resource name of the subscription. - - Format: ``subscriptions/{subscription}`` - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - - -class ListSubscriptionsRequest(proto.Message): - r"""The request message for - [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. - - Attributes: - page_size (int): - Optional. The maximum number of subscriptions to return. The - service might return fewer than this value. - - If unspecified or set to ``0``, up to 50 subscriptions are - returned. - - The maximum value is 100. If you specify a value more than - 100, the system only returns 100 subscriptions. - page_token (str): - Optional. A page token, received from a - previous list subscriptions call. Provide this - parameter to retrieve the subsequent page. - - When paginating, the filter value should match - the call that provided the page token. Passing a - different value might lead to unexpected - results. - filter (str): - Required. A query filter. - - You can filter subscriptions by event type (``event_types``) - and target resource (``target_resource``). - - You must specify at least one event type in your query. To - filter for multiple event types, use the ``OR`` operator. - - To filter by both event type and target resource, use the - ``AND`` operator and specify the full resource name, such as - ``//chat.googleapis.com/spaces/{space}``. - - For example, the following queries are valid: - - :: - - event_types:"google.workspace.chat.membership.v1.updated" OR - event_types:"google.workspace.chat.message.v1.created" - - event_types:"google.workspace.chat.message.v1.created" AND - target_resource="//chat.googleapis.com/spaces/{space}" - - ( event_types:"google.workspace.chat.membership.v1.updated" OR - event_types:"google.workspace.chat.message.v1.created" ) AND - target_resource="//chat.googleapis.com/spaces/{space}" - - The server rejects invalid queries with an - ``INVALID_ARGUMENT`` error. - """ - - page_size: int = proto.Field( - proto.INT32, - number=1, - ) - page_token: str = proto.Field( - proto.STRING, - number=2, - ) - filter: str = proto.Field( - proto.STRING, - number=3, - ) - - -class ListSubscriptionsResponse(proto.Message): - r"""The response message for - [SubscriptionsService.ListSubscriptions][google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions]. - - Attributes: - subscriptions (MutableSequence[google.apps.events_subscriptions_v1.types.Subscription]): - List of subscriptions. - next_page_token (str): - A token, which can be sent as ``page_token`` to retrieve the - next page. If this field is omitted, there are no subsequent - pages. - """ - - @property - def raw_page(self): - return self - - subscriptions: MutableSequence[ - subscription_resource.Subscription - ] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=subscription_resource.Subscription, - ) - next_page_token: str = proto.Field( - proto.STRING, - number=2, - ) - - -class UpdateSubscriptionMetadata(proto.Message): - r"""Metadata for UpdateSubscription LRO.""" - - -class CreateSubscriptionMetadata(proto.Message): - r"""Metadata for CreateSubscription LRO.""" - - -class DeleteSubscriptionMetadata(proto.Message): - r"""Metadata for DeleteSubscription LRO.""" - - -class ReactivateSubscriptionMetadata(proto.Message): - r"""Metadata for ReactivateSubscription LRO.""" - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-apps-events-subscriptions/mypy.ini b/packages/google-apps-events-subscriptions/mypy.ini deleted file mode 100644 index 574c5aed394b..000000000000 --- a/packages/google-apps-events-subscriptions/mypy.ini +++ /dev/null @@ -1,3 +0,0 @@ -[mypy] -python_version = 3.7 -namespace_packages = True diff --git a/packages/google-apps-events-subscriptions/noxfile.py b/packages/google-apps-events-subscriptions/noxfile.py deleted file mode 100644 index 1e6cd48d0529..000000000000 --- a/packages/google-apps-events-subscriptions/noxfile.py +++ /dev/null @@ -1,428 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2023 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. - -# Generated by synthtool. DO NOT EDIT! - -from __future__ import absolute_import - -import os -import pathlib -import re -import shutil -from typing import Dict, List -import warnings - -import nox - -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" - -LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] - - -DEFAULT_PYTHON_VERSION = "3.10" - -UNIT_TEST_PYTHON_VERSIONS: List[str] = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] -UNIT_TEST_STANDARD_DEPENDENCIES = [ - "mock", - "asyncmock", - "pytest", - "pytest-cov", - "pytest-asyncio", -] -UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] -UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] -UNIT_TEST_DEPENDENCIES: List[str] = [] -UNIT_TEST_EXTRAS: List[str] = [] -UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} - -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12"] -SYSTEM_TEST_STANDARD_DEPENDENCIES = [ - "mock", - "pytest", - "google-cloud-testutils", -] -SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] -SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] -SYSTEM_TEST_DEPENDENCIES: List[str] = [] -SYSTEM_TEST_EXTRAS: List[str] = [] -SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} - -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): - """Run linters. - - Returns a failure if the linters find linting errors or sufficiently - serious code quality issues. - """ - session.install("flake8", BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) - - session.run("flake8", "google", "tests") - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def format(session): - """ - Run isort to sort imports. Then run black - to format code to uniform standard. - """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections - session.run( - "isort", - "--fss", - *LINT_PATHS, - ) - session.run( - "black", - *LINT_PATHS, - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def lint_setup_py(session): - """Verify that setup.py is valid (including RST check).""" - session.install("docutils", "pygments") - session.run("python", "setup.py", "check", "--restructuredtext", "--strict") - - -def install_unittest_dependencies(session, *constraints): - standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES - session.install(*standard_deps, *constraints) - - if UNIT_TEST_EXTERNAL_DEPENDENCIES: - warnings.warn( - "'unit_test_external_dependencies' is deprecated. Instead, please " - "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", - DeprecationWarning, - ) - session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) - - if UNIT_TEST_LOCAL_DEPENDENCIES: - session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) - - if UNIT_TEST_EXTRAS_BY_PYTHON: - extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) - elif UNIT_TEST_EXTRAS: - extras = UNIT_TEST_EXTRAS - else: - extras = [] - - if extras: - session.install("-e", f".[{','.join(extras)}]", *constraints) - else: - session.install("-e", ".", *constraints) - - -def default(session): - # Install all test dependencies, then install this package in-place. - - constraints_path = str( - CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" - ) - install_unittest_dependencies(session, "-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", - "--cov=tests/unit", - "--cov-append", - "--cov-config=.coveragerc", - "--cov-report=", - "--cov-fail-under=0", - os.path.join("tests", "unit"), - *session.posargs, - ) - - -@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) -def unit(session): - """Run the unit test suite.""" - default(session) - - -def install_systemtest_dependencies(session, *constraints): - # Use pre-release gRPC for system tests. - # Exclude version 1.52.0rc1 which has a known issue. - # See https://github.com/grpc/grpc/issues/32163 - session.install("--pre", "grpcio!=1.52.0rc1") - - session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: - session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_LOCAL_DEPENDENCIES: - session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_DEPENDENCIES: - session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_EXTRAS_BY_PYTHON: - extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) - elif SYSTEM_TEST_EXTRAS: - extras = SYSTEM_TEST_EXTRAS - else: - extras = [] - - if extras: - session.install("-e", f".[{','.join(extras)}]", *constraints) - else: - session.install("-e", ".", *constraints) - - -@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") - - # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. - if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": - session.skip("RUN_SYSTEM_TESTS is set to false, skipping") - # 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) - # Sanity check: only run tests if found. - if not system_test_exists and not system_test_folder_exists: - session.skip("System tests were not found") - - install_systemtest_dependencies(session, "-c", constraints_path) - - # Run py.test against the system tests. - if system_test_exists: - 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", - f"--junitxml=system_{session.python}_sponge_log.xml", - system_test_folder_path, - *session.posargs, - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def cover(session): - """Run the final coverage report. - - This outputs the coverage report aggregating coverage from the unit - test runs (not system test runs), and then erases coverage data. - """ - session.install("coverage", "pytest-cov") - session.run("coverage", "report", "--show-missing", "--fail-under=100") - - session.run("coverage", "erase") - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def docs(session): - """Build the docs for this library.""" - - session.install("-e", ".") - session.install( - # We need to pin to specific versions of the `sphinxcontrib-*` packages - # which still support sphinx 4.x. - # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 - # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. - "sphinxcontrib-applehelp==1.0.4", - "sphinxcontrib-devhelp==1.0.2", - "sphinxcontrib-htmlhelp==2.0.1", - "sphinxcontrib-qthelp==1.0.3", - "sphinxcontrib-serializinghtml==1.1.5", - "sphinx==4.5.0", - "alabaster", - "recommonmark", - ) - - shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) - session.run( - "sphinx-build", - "-W", # warnings as errors - "-T", # show full traceback on exception - "-N", # no colors - "-b", - "html", - "-d", - os.path.join("docs", "_build", "doctrees", ""), - os.path.join("docs", ""), - os.path.join("docs", "_build", "html", ""), - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def docfx(session): - """Build the docfx yaml files for this library.""" - - session.install("-e", ".") - session.install( - # We need to pin to specific versions of the `sphinxcontrib-*` packages - # which still support sphinx 4.x. - # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 - # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. - "sphinxcontrib-applehelp==1.0.4", - "sphinxcontrib-devhelp==1.0.2", - "sphinxcontrib-htmlhelp==2.0.1", - "sphinxcontrib-qthelp==1.0.3", - "sphinxcontrib-serializinghtml==1.1.5", - "gcp-sphinx-docfx-yaml", - "alabaster", - "recommonmark", - ) - - shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) - session.run( - "sphinx-build", - "-T", # show full traceback on exception - "-N", # no colors - "-D", - ( - "extensions=sphinx.ext.autodoc," - "sphinx.ext.autosummary," - "docfx_yaml.extension," - "sphinx.ext.intersphinx," - "sphinx.ext.coverage," - "sphinx.ext.napoleon," - "sphinx.ext.todo," - "sphinx.ext.viewcode," - "recommonmark" - ), - "-b", - "html", - "-d", - os.path.join("docs", "_build", "doctrees", ""), - os.path.join("docs", ""), - os.path.join("docs", "_build", "html", ""), - ) - - -@nox.session(python="3.12") -def prerelease_deps(session): - """Run all tests with prerelease versions of dependencies installed.""" - - # Install all dependencies - session.install("-e", ".[all, tests, tracing]") - unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES - session.install(*unit_deps_all) - system_deps_all = ( - SYSTEM_TEST_STANDARD_DEPENDENCIES - + SYSTEM_TEST_EXTERNAL_DEPENDENCIES - + SYSTEM_TEST_EXTRAS - ) - session.install(*system_deps_all) - - # Because we test minimum dependency versions on the minimum Python - # version, the first version we test with in the unit tests sessions has a - # constraints file containing all dependencies and extras. - with open( - CURRENT_DIRECTORY - / "testing" - / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt", - encoding="utf-8", - ) as constraints_file: - constraints_text = constraints_file.read() - - # Ignore leading whitespace and comment lines. - constraints_deps = [ - match.group(1) - for match in re.finditer( - r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE - ) - ] - - session.install(*constraints_deps) - - prerel_deps = [ - "protobuf", - # dependency of grpc - "six", - "googleapis-common-protos", - # Exclude version 1.52.0rc1 which has a known issue. See https://github.com/grpc/grpc/issues/32163 - "grpcio!=1.52.0rc1", - "grpcio-status", - "google-api-core", - "google-auth", - "proto-plus", - "google-cloud-testutils", - # dependencies of google-cloud-testutils" - "click", - ] - - for dep in prerel_deps: - session.install("--pre", "--no-deps", "--upgrade", dep) - - # Remaining dependencies - other_deps = [ - "requests", - ] - session.install(*other_deps) - - # Print out prerelease package versions - session.run( - "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" - ) - session.run("python", "-c", "import grpc; print(grpc.__version__)") - session.run("python", "-c", "import google.auth; print(google.auth.__version__)") - - session.run("py.test", "tests/unit") diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json b/packages/google-apps-events-subscriptions/samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json deleted file mode 100644 index ef49bdf7102e..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json +++ /dev/null @@ -1,1005 +0,0 @@ -{ - "clientLibrary": { - "apis": [ - { - "id": "google.apps.events.subscriptions.v1", - "version": "v1" - } - ], - "language": "PYTHON", - "name": "google-apps-events-subscriptions", - "version": "0.1.0" - }, - "snippets": [ - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", - "shortName": "SubscriptionsServiceAsyncClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.create_subscription", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "CreateSubscription" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.CreateSubscriptionRequest" - }, - { - "name": "subscription", - "type": "google.apps.events_subscriptions_v1.types.Subscription" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "create_subscription" - }, - "description": "Sample for CreateSubscription", - "file": "workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_async", - "segments": [ - { - "end": 60, - "start": 27, - "type": "FULL" - }, - { - "end": 60, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 50, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 57, - "start": 51, - "type": "REQUEST_EXECUTION" - }, - { - "end": 61, - "start": 58, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", - "shortName": "SubscriptionsServiceClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.create_subscription", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.CreateSubscription", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "CreateSubscription" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.CreateSubscriptionRequest" - }, - { - "name": "subscription", - "type": "google.apps.events_subscriptions_v1.types.Subscription" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation.Operation", - "shortName": "create_subscription" - }, - "description": "Sample for CreateSubscription", - "file": "workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_sync", - "segments": [ - { - "end": 60, - "start": 27, - "type": "FULL" - }, - { - "end": 60, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 50, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 57, - "start": 51, - "type": "REQUEST_EXECUTION" - }, - { - "end": 61, - "start": 58, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", - "shortName": "SubscriptionsServiceAsyncClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.delete_subscription", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "DeleteSubscription" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.DeleteSubscriptionRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "delete_subscription" - }, - "description": "Sample for DeleteSubscription", - "file": "workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_async", - "segments": [ - { - "end": 55, - "start": 27, - "type": "FULL" - }, - { - "end": 55, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 52, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 56, - "start": 53, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", - "shortName": "SubscriptionsServiceClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.delete_subscription", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.DeleteSubscription", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "DeleteSubscription" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.DeleteSubscriptionRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation.Operation", - "shortName": "delete_subscription" - }, - "description": "Sample for DeleteSubscription", - "file": "workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_sync", - "segments": [ - { - "end": 55, - "start": 27, - "type": "FULL" - }, - { - "end": 55, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 52, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 56, - "start": 53, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", - "shortName": "SubscriptionsServiceAsyncClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.get_subscription", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "GetSubscription" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.GetSubscriptionRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.apps.events_subscriptions_v1.types.Subscription", - "shortName": "get_subscription" - }, - "description": "Sample for GetSubscription", - "file": "workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_GetSubscription_async", - "segments": [ - { - "end": 51, - "start": 27, - "type": "FULL" - }, - { - "end": 51, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 52, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", - "shortName": "SubscriptionsServiceClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.get_subscription", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.GetSubscription", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "GetSubscription" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.GetSubscriptionRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.apps.events_subscriptions_v1.types.Subscription", - "shortName": "get_subscription" - }, - "description": "Sample for GetSubscription", - "file": "workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_GetSubscription_sync", - "segments": [ - { - "end": 51, - "start": 27, - "type": "FULL" - }, - { - "end": 51, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 52, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", - "shortName": "SubscriptionsServiceAsyncClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.list_subscriptions", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "ListSubscriptions" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest" - }, - { - "name": "page_size", - "type": "int" - }, - { - "name": "page_token", - "type": "str" - }, - { - "name": "filter", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.apps.events_subscriptions_v1.services.subscriptions_service.pagers.ListSubscriptionsAsyncPager", - "shortName": "list_subscriptions" - }, - "description": "Sample for ListSubscriptions", - "file": "workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_async", - "segments": [ - { - "end": 52, - "start": 27, - "type": "FULL" - }, - { - "end": 52, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 53, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", - "shortName": "SubscriptionsServiceClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.list_subscriptions", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.ListSubscriptions", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "ListSubscriptions" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.ListSubscriptionsRequest" - }, - { - "name": "page_size", - "type": "int" - }, - { - "name": "page_token", - "type": "str" - }, - { - "name": "filter", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.apps.events_subscriptions_v1.services.subscriptions_service.pagers.ListSubscriptionsPager", - "shortName": "list_subscriptions" - }, - "description": "Sample for ListSubscriptions", - "file": "workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_sync", - "segments": [ - { - "end": 52, - "start": 27, - "type": "FULL" - }, - { - "end": 52, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 53, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", - "shortName": "SubscriptionsServiceAsyncClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.reactivate_subscription", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "ReactivateSubscription" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.ReactivateSubscriptionRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "reactivate_subscription" - }, - "description": "Sample for ReactivateSubscription", - "file": "workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_async", - "segments": [ - { - "end": 55, - "start": 27, - "type": "FULL" - }, - { - "end": 55, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 52, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 56, - "start": 53, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", - "shortName": "SubscriptionsServiceClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.reactivate_subscription", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.ReactivateSubscription", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "ReactivateSubscription" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.ReactivateSubscriptionRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation.Operation", - "shortName": "reactivate_subscription" - }, - "description": "Sample for ReactivateSubscription", - "file": "workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_sync", - "segments": [ - { - "end": 55, - "start": 27, - "type": "FULL" - }, - { - "end": 55, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 52, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 56, - "start": 53, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient", - "shortName": "SubscriptionsServiceAsyncClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceAsyncClient.update_subscription", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "UpdateSubscription" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.UpdateSubscriptionRequest" - }, - { - "name": "subscription", - "type": "google.apps.events_subscriptions_v1.types.Subscription" - }, - { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "update_subscription" - }, - "description": "Sample for UpdateSubscription", - "file": "workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_async", - "segments": [ - { - "end": 60, - "start": 27, - "type": "FULL" - }, - { - "end": 60, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 50, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 57, - "start": 51, - "type": "REQUEST_EXECUTION" - }, - { - "end": 61, - "start": 58, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient", - "shortName": "SubscriptionsServiceClient" - }, - "fullName": "google.apps.events_subscriptions_v1.SubscriptionsServiceClient.update_subscription", - "method": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService.UpdateSubscription", - "service": { - "fullName": "google.apps.events.subscriptions.v1.SubscriptionsService", - "shortName": "SubscriptionsService" - }, - "shortName": "UpdateSubscription" - }, - "parameters": [ - { - "name": "request", - "type": "google.apps.events_subscriptions_v1.types.UpdateSubscriptionRequest" - }, - { - "name": "subscription", - "type": "google.apps.events_subscriptions_v1.types.Subscription" - }, - { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation.Operation", - "shortName": "update_subscription" - }, - "description": "Sample for UpdateSubscription", - "file": "workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_sync", - "segments": [ - { - "end": 60, - "start": 27, - "type": "FULL" - }, - { - "end": 60, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 50, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 57, - "start": 51, - "type": "REQUEST_EXECUTION" - }, - { - "end": 61, - "start": 58, - "type": "RESPONSE_HANDLING" - } - ], - "title": "workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py" - } - ] -} diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py deleted file mode 100644 index f1c3db149d0e..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_async.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for CreateSubscription -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -async def sample_create_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - subscription = events_subscriptions_v1.Subscription() - subscription.target_resource = "target_resource_value" - subscription.event_types = ['event_types_value1', 'event_types_value2'] - subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" - - request = events_subscriptions_v1.CreateSubscriptionRequest( - subscription=subscription, - ) - - # Make the request - operation = client.create_subscription(request=request) - - print("Waiting for operation to complete...") - - response = (await operation).result() - - # Handle the response - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py deleted file mode 100644 index 0cfa43c88086..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_create_subscription_sync.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for CreateSubscription -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -def sample_create_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - subscription = events_subscriptions_v1.Subscription() - subscription.target_resource = "target_resource_value" - subscription.event_types = ['event_types_value1', 'event_types_value2'] - subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" - - request = events_subscriptions_v1.CreateSubscriptionRequest( - subscription=subscription, - ) - - # Make the request - operation = client.create_subscription(request=request) - - print("Waiting for operation to complete...") - - response = operation.result() - - # Handle the response - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_CreateSubscription_sync] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py deleted file mode 100644 index 7b1a505e1de4..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_async.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for DeleteSubscription -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -async def sample_delete_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.DeleteSubscriptionRequest( - name="name_value", - ) - - # Make the request - operation = client.delete_subscription(request=request) - - print("Waiting for operation to complete...") - - response = (await operation).result() - - # Handle the response - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py deleted file mode 100644 index aef41f38ee0b..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_delete_subscription_sync.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for DeleteSubscription -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -def sample_delete_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.DeleteSubscriptionRequest( - name="name_value", - ) - - # Make the request - operation = client.delete_subscription(request=request) - - print("Waiting for operation to complete...") - - response = operation.result() - - # Handle the response - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_DeleteSubscription_sync] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py deleted file mode 100644 index 24fd9dced74d..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetSubscription -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_GetSubscription_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -async def sample_get_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.GetSubscriptionRequest( - name="name_value", - ) - - # Make the request - response = await client.get_subscription(request=request) - - # Handle the response - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_GetSubscription_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py deleted file mode 100644 index 1907421b0797..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_get_subscription_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetSubscription -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_GetSubscription_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -def sample_get_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.GetSubscriptionRequest( - name="name_value", - ) - - # Make the request - response = client.get_subscription(request=request) - - # Handle the response - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_GetSubscription_sync] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py deleted file mode 100644 index b9fa0148c6ba..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_async.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListSubscriptions -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -async def sample_list_subscriptions(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.ListSubscriptionsRequest( - filter="filter_value", - ) - - # Make the request - page_result = client.list_subscriptions(request=request) - - # Handle the response - async for response in page_result: - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py deleted file mode 100644 index 0befeb3b40b8..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_list_subscriptions_sync.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListSubscriptions -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -def sample_list_subscriptions(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.ListSubscriptionsRequest( - filter="filter_value", - ) - - # Make the request - page_result = client.list_subscriptions(request=request) - - # Handle the response - for response in page_result: - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_ListSubscriptions_sync] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py deleted file mode 100644 index 4b664d9ad0b1..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_async.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ReactivateSubscription -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -async def sample_reactivate_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.ReactivateSubscriptionRequest( - name="name_value", - ) - - # Make the request - operation = client.reactivate_subscription(request=request) - - print("Waiting for operation to complete...") - - response = (await operation).result() - - # Handle the response - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py deleted file mode 100644 index 82deada37c21..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_reactivate_subscription_sync.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ReactivateSubscription -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -def sample_reactivate_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - request = events_subscriptions_v1.ReactivateSubscriptionRequest( - name="name_value", - ) - - # Make the request - operation = client.reactivate_subscription(request=request) - - print("Waiting for operation to complete...") - - response = operation.result() - - # Handle the response - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_ReactivateSubscription_sync] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py deleted file mode 100644 index abb3082ac2db..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_async.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for UpdateSubscription -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -async def sample_update_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceAsyncClient() - - # Initialize request argument(s) - subscription = events_subscriptions_v1.Subscription() - subscription.target_resource = "target_resource_value" - subscription.event_types = ['event_types_value1', 'event_types_value2'] - subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" - - request = events_subscriptions_v1.UpdateSubscriptionRequest( - subscription=subscription, - ) - - # Make the request - operation = client.update_subscription(request=request) - - print("Waiting for operation to complete...") - - response = (await operation).result() - - # Handle the response - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_async] diff --git a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py b/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py deleted file mode 100644 index 8d908b3d6ea6..000000000000 --- a/packages/google-apps-events-subscriptions/samples/generated_samples/workspaceevents_v1_generated_subscriptions_service_update_subscription_sync.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -# Generated code. DO NOT EDIT! -# -# Snippet for UpdateSubscription -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-apps-events-subscriptions - - -# [START workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.apps import events_subscriptions_v1 - - -def sample_update_subscription(): - # Create a client - client = events_subscriptions_v1.SubscriptionsServiceClient() - - # Initialize request argument(s) - subscription = events_subscriptions_v1.Subscription() - subscription.target_resource = "target_resource_value" - subscription.event_types = ['event_types_value1', 'event_types_value2'] - subscription.notification_endpoint.pubsub_topic = "pubsub_topic_value" - - request = events_subscriptions_v1.UpdateSubscriptionRequest( - subscription=subscription, - ) - - # Make the request - operation = client.update_subscription(request=request) - - print("Waiting for operation to complete...") - - response = operation.result() - - # Handle the response - print(response) - -# [END workspaceevents_v1_generated_SubscriptionsService_UpdateSubscription_sync] diff --git a/packages/google-apps-events-subscriptions/scripts/decrypt-secrets.sh b/packages/google-apps-events-subscriptions/scripts/decrypt-secrets.sh deleted file mode 100755 index 0018b421ddf8..000000000000 --- a/packages/google-apps-events-subscriptions/scripts/decrypt-secrets.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -# Copyright 2023 Google LLC All rights reserved. -# -# 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. - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -ROOT=$( dirname "$DIR" ) - -# Work from the project root. -cd $ROOT - -# Prevent it from overriding files. -# We recommend that sample authors use their own service account files and cloud project. -# In that case, they are supposed to prepare these files by themselves. -if [[ -f "testing/test-env.sh" ]] || \ - [[ -f "testing/service-account.json" ]] || \ - [[ -f "testing/client-secrets.json" ]]; then - echo "One or more target files exist, aborting." - exit 1 -fi - -# Use SECRET_MANAGER_PROJECT if set, fallback to cloud-devrel-kokoro-resources. -PROJECT_ID="${SECRET_MANAGER_PROJECT:-cloud-devrel-kokoro-resources}" - -gcloud secrets versions access latest --secret="python-docs-samples-test-env" \ - --project="${PROJECT_ID}" \ - > testing/test-env.sh -gcloud secrets versions access latest \ - --secret="python-docs-samples-service-account" \ - --project="${PROJECT_ID}" \ - > testing/service-account.json -gcloud secrets versions access latest \ - --secret="python-docs-samples-client-secrets" \ - --project="${PROJECT_ID}" \ - > testing/client-secrets.json diff --git a/packages/google-apps-events-subscriptions/scripts/fixup_events_subscriptions_v1_keywords.py b/packages/google-apps-events-subscriptions/scripts/fixup_events_subscriptions_v1_keywords.py deleted file mode 100644 index 749c9a3926fa..000000000000 --- a/packages/google-apps-events-subscriptions/scripts/fixup_events_subscriptions_v1_keywords.py +++ /dev/null @@ -1,181 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -import argparse -import os -import libcst as cst -import pathlib -import sys -from typing import (Any, Callable, Dict, List, Sequence, Tuple) - - -def partition( - predicate: Callable[[Any], bool], - iterator: Sequence[Any] -) -> Tuple[List[Any], List[Any]]: - """A stable, out-of-place partition.""" - results = ([], []) - - for i in iterator: - results[int(predicate(i))].append(i) - - # Returns trueList, falseList - return results[1], results[0] - - -class events_subscriptionsCallTransformer(cst.CSTTransformer): - CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') - METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'create_subscription': ('subscription', 'validate_only', ), - 'delete_subscription': ('name', 'validate_only', 'allow_missing', 'etag', ), - 'get_subscription': ('name', ), - 'list_subscriptions': ('filter', 'page_size', 'page_token', ), - 'reactivate_subscription': ('name', ), - 'update_subscription': ('subscription', 'update_mask', 'validate_only', ), - } - - def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: - try: - key = original.func.attr.value - kword_params = self.METHOD_TO_PARAMS[key] - except (AttributeError, KeyError): - # Either not a method from the API or too convoluted to be sure. - return updated - - # If the existing code is valid, keyword args come after positional args. - # Therefore, all positional args must map to the first parameters. - args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) - if any(k.keyword.value == "request" for k in kwargs): - # We've already fixed this file, don't fix it again. - return updated - - kwargs, ctrl_kwargs = partition( - lambda a: a.keyword.value not in self.CTRL_PARAMS, - kwargs - ) - - args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] - ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) - for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) - - request_arg = cst.Arg( - value=cst.Dict([ - cst.DictElement( - cst.SimpleString("'{}'".format(name)), -cst.Element(value=arg.value) - ) - # Note: the args + kwargs looks silly, but keep in mind that - # the control parameters had to be stripped out, and that - # those could have been passed positionally or by keyword. - for name, arg in zip(kword_params, args + kwargs)]), - keyword=cst.Name("request") - ) - - return updated.with_changes( - args=[request_arg] + ctrl_kwargs - ) - - -def fix_files( - in_dir: pathlib.Path, - out_dir: pathlib.Path, - *, - transformer=events_subscriptionsCallTransformer(), -): - """Duplicate the input dir to the output dir, fixing file method calls. - - Preconditions: - * in_dir is a real directory - * out_dir is a real, empty directory - """ - pyfile_gen = ( - pathlib.Path(os.path.join(root, f)) - for root, _, files in os.walk(in_dir) - for f in files if os.path.splitext(f)[1] == ".py" - ) - - for fpath in pyfile_gen: - with open(fpath, 'r') as f: - src = f.read() - - # Parse the code and insert method call fixes. - tree = cst.parse_module(src) - updated = tree.visit(transformer) - - # Create the path and directory structure for the new file. - updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) - updated_path.parent.mkdir(parents=True, exist_ok=True) - - # Generate the updated source file at the corresponding path. - with open(updated_path, 'w') as f: - f.write(updated.code) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser( - description="""Fix up source that uses the events_subscriptions client library. - -The existing sources are NOT overwritten but are copied to output_dir with changes made. - -Note: This tool operates at a best-effort level at converting positional - parameters in client method calls to keyword based parameters. - Cases where it WILL FAIL include - A) * or ** expansion in a method call. - B) Calls via function or method alias (includes free function calls) - C) Indirect or dispatched calls (e.g. the method is looked up dynamically) - - These all constitute false negatives. The tool will also detect false - positives when an API method shares a name with another method. -""") - parser.add_argument( - '-d', - '--input-directory', - required=True, - dest='input_dir', - help='the input directory to walk for python files to fix up', - ) - parser.add_argument( - '-o', - '--output-directory', - required=True, - dest='output_dir', - help='the directory to output files fixed via un-flattening', - ) - args = parser.parse_args() - input_dir = pathlib.Path(args.input_dir) - output_dir = pathlib.Path(args.output_dir) - if not input_dir.is_dir(): - print( - f"input directory '{input_dir}' does not exist or is not a directory", - file=sys.stderr, - ) - sys.exit(-1) - - if not output_dir.is_dir(): - print( - f"output directory '{output_dir}' does not exist or is not a directory", - file=sys.stderr, - ) - sys.exit(-1) - - if os.listdir(output_dir): - print( - f"output directory '{output_dir}' is not empty", - file=sys.stderr, - ) - sys.exit(-1) - - fix_files(input_dir, output_dir) diff --git a/packages/google-apps-events-subscriptions/setup.py b/packages/google-apps-events-subscriptions/setup.py deleted file mode 100644 index 701e986c32eb..000000000000 --- a/packages/google-apps-events-subscriptions/setup.py +++ /dev/null @@ -1,93 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -import io -import os -import re - -import setuptools # type: ignore - -package_root = os.path.abspath(os.path.dirname(__file__)) - -name = "google-apps-events-subscriptions" - - -description = "Google Apps Events Subscriptions API client library" - -version = None - -with open( - os.path.join(package_root, "google/apps/events_subscriptions/gapic_version.py") -) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) - assert len(version_candidates) == 1 - version = version_candidates[0] - -if version[0] == "0": - release_status = "Development Status :: 4 - Beta" -else: - release_status = "Development Status :: 5 - Production/Stable" - -dependencies = [ - "google-api-core[grpc] >= 1.34.1, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", - "google-auth >= 2.14.1, <3.0.0dev", - "proto-plus >= 1.22.3, <2.0.0dev", - "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", -] -url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-events-subscriptions" - -package_root = os.path.abspath(os.path.dirname(__file__)) - -readme_filename = os.path.join(package_root, "README.rst") -with io.open(readme_filename, encoding="utf-8") as readme_file: - readme = readme_file.read() - -packages = [ - package - for package in setuptools.find_namespace_packages() - if package.startswith("google") -] - -setuptools.setup( - name=name, - version=version, - description=description, - long_description=readme, - author="Google LLC", - author_email="googleapis-packages@google.com", - license="Apache 2.0", - url=url, - classifiers=[ - release_status, - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Operating System :: OS Independent", - "Topic :: Internet", - ], - platforms="Posix; MacOS X; Windows", - packages=packages, - python_requires=">=3.7", - install_requires=dependencies, - include_package_data=True, - zip_safe=False, -) diff --git a/packages/google-apps-events-subscriptions/testing/.gitignore b/packages/google-apps-events-subscriptions/testing/.gitignore deleted file mode 100644 index b05fbd630881..000000000000 --- a/packages/google-apps-events-subscriptions/testing/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -test-env.sh -service-account.json -client-secrets.json \ No newline at end of file diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.10.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.10.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/packages/google-apps-events-subscriptions/testing/constraints-3.10.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core -proto-plus -protobuf diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.11.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.11.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/packages/google-apps-events-subscriptions/testing/constraints-3.11.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core -proto-plus -protobuf diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.12.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.12.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/packages/google-apps-events-subscriptions/testing/constraints-3.12.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core -proto-plus -protobuf diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.7.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.7.txt deleted file mode 100644 index b8a550c73855..000000000000 --- a/packages/google-apps-events-subscriptions/testing/constraints-3.7.txt +++ /dev/null @@ -1,10 +0,0 @@ -# This constraints file is used to check that lower bounds -# are correct in setup.py -# List all library dependencies and extras in this file. -# Pin the version to the lower bound. -# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", -# Then this file should have google-cloud-foo==1.14.0 -google-api-core==1.34.1 -google-auth==2.14.1 -proto-plus==1.22.3 -protobuf==3.19.5 diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.8.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.8.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/packages/google-apps-events-subscriptions/testing/constraints-3.8.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core -proto-plus -protobuf diff --git a/packages/google-apps-events-subscriptions/testing/constraints-3.9.txt b/packages/google-apps-events-subscriptions/testing/constraints-3.9.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/packages/google-apps-events-subscriptions/testing/constraints-3.9.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core -proto-plus -protobuf diff --git a/packages/google-apps-events-subscriptions/tests/__init__.py b/packages/google-apps-events-subscriptions/tests/__init__.py deleted file mode 100644 index 89a37dc92c5a..000000000000 --- a/packages/google-apps-events-subscriptions/tests/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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/packages/google-apps-events-subscriptions/tests/unit/__init__.py b/packages/google-apps-events-subscriptions/tests/unit/__init__.py deleted file mode 100644 index 89a37dc92c5a..000000000000 --- a/packages/google-apps-events-subscriptions/tests/unit/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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/packages/google-apps-events-subscriptions/tests/unit/gapic/__init__.py b/packages/google-apps-events-subscriptions/tests/unit/gapic/__init__.py deleted file mode 100644 index 89a37dc92c5a..000000000000 --- a/packages/google-apps-events-subscriptions/tests/unit/gapic/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/__init__.py b/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/__init__.py deleted file mode 100644 index 89a37dc92c5a..000000000000 --- a/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/test_subscriptions_service.py b/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/test_subscriptions_service.py deleted file mode 100644 index 91b4e72cae36..000000000000 --- a/packages/google-apps-events-subscriptions/tests/unit/gapic/events_subscriptions_v1/test_subscriptions_service.py +++ /dev/null @@ -1,5833 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 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. -# -import os - -# try/except added for compatibility with python < 3.8 -try: - from unittest import mock - from unittest.mock import AsyncMock # pragma: NO COVER -except ImportError: # pragma: NO COVER - import mock - -from collections.abc import Iterable -import json -import math - -from google.api_core import ( - future, - gapic_v1, - grpc_helpers, - grpc_helpers_async, - operation, - operations_v1, - path_template, -) -from google.api_core import api_core_version, client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import operation_async # type: ignore -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.longrunning import operations_pb2 # type: ignore -from google.oauth2 import service_account -from google.protobuf import duration_pb2 # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import json_format -from google.protobuf import timestamp_pb2 # type: ignore -import grpc -from grpc.experimental import aio -from proto.marshal.rules import wrappers -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest -from requests import PreparedRequest, Request, Response -from requests.sessions import Session - -from google.apps.events_subscriptions_v1.services.subscriptions_service import ( - SubscriptionsServiceAsyncClient, - SubscriptionsServiceClient, - pagers, - transports, -) -from google.apps.events_subscriptions_v1.types import ( - subscription_resource, - subscriptions_service, -) - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return ( - "foo.googleapis.com" - if ("localhost" in client.DEFAULT_ENDPOINT) - else client.DEFAULT_ENDPOINT - ) - - -# If default endpoint template is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint template so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint_template(client): - return ( - "test.{UNIVERSE_DOMAIN}" - if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) - else client._DEFAULT_ENDPOINT_TEMPLATE - ) - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert SubscriptionsServiceClient._get_default_mtls_endpoint(None) is None - assert ( - SubscriptionsServiceClient._get_default_mtls_endpoint(api_endpoint) - == api_mtls_endpoint - ) - assert ( - SubscriptionsServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) - == api_mtls_endpoint - ) - assert ( - SubscriptionsServiceClient._get_default_mtls_endpoint(sandbox_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - SubscriptionsServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - SubscriptionsServiceClient._get_default_mtls_endpoint(non_googleapi) - == non_googleapi - ) - - -def test__read_environment_variables(): - assert SubscriptionsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert SubscriptionsServiceClient._read_environment_variables() == ( - True, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - assert SubscriptionsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError) as excinfo: - SubscriptionsServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - assert SubscriptionsServiceClient._read_environment_variables() == ( - False, - "never", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - assert SubscriptionsServiceClient._read_environment_variables() == ( - False, - "always", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): - assert SubscriptionsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - SubscriptionsServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): - assert SubscriptionsServiceClient._read_environment_variables() == ( - False, - "auto", - "foo.com", - ) - - -def test__get_client_cert_source(): - mock_provided_cert_source = mock.Mock() - mock_default_cert_source = mock.Mock() - - assert SubscriptionsServiceClient._get_client_cert_source(None, False) is None - assert ( - SubscriptionsServiceClient._get_client_cert_source( - mock_provided_cert_source, False - ) - is None - ) - assert ( - SubscriptionsServiceClient._get_client_cert_source( - mock_provided_cert_source, True - ) - == mock_provided_cert_source - ) - - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", return_value=True - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=mock_default_cert_source, - ): - assert ( - SubscriptionsServiceClient._get_client_cert_source(None, True) - is mock_default_cert_source - ) - assert ( - SubscriptionsServiceClient._get_client_cert_source( - mock_provided_cert_source, "true" - ) - is mock_provided_cert_source - ) - - -@mock.patch.object( - SubscriptionsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(SubscriptionsServiceClient), -) -@mock.patch.object( - SubscriptionsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(SubscriptionsServiceAsyncClient), -) -def test__get_api_endpoint(): - api_override = "foo.com" - mock_client_cert_source = mock.Mock() - default_universe = SubscriptionsServiceClient._DEFAULT_UNIVERSE - default_endpoint = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=default_universe - ) - mock_universe = "bar.com" - mock_endpoint = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=mock_universe - ) - - assert ( - SubscriptionsServiceClient._get_api_endpoint( - api_override, mock_client_cert_source, default_universe, "always" - ) - == api_override - ) - assert ( - SubscriptionsServiceClient._get_api_endpoint( - None, mock_client_cert_source, default_universe, "auto" - ) - == SubscriptionsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - SubscriptionsServiceClient._get_api_endpoint( - None, None, default_universe, "auto" - ) - == default_endpoint - ) - assert ( - SubscriptionsServiceClient._get_api_endpoint( - None, None, default_universe, "always" - ) - == SubscriptionsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - SubscriptionsServiceClient._get_api_endpoint( - None, mock_client_cert_source, default_universe, "always" - ) - == SubscriptionsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - SubscriptionsServiceClient._get_api_endpoint(None, None, mock_universe, "never") - == mock_endpoint - ) - assert ( - SubscriptionsServiceClient._get_api_endpoint( - None, None, default_universe, "never" - ) - == default_endpoint - ) - - with pytest.raises(MutualTLSChannelError) as excinfo: - SubscriptionsServiceClient._get_api_endpoint( - None, mock_client_cert_source, mock_universe, "auto" - ) - assert ( - str(excinfo.value) - == "mTLS is not supported in any universe other than googleapis.com." - ) - - -def test__get_universe_domain(): - client_universe_domain = "foo.com" - universe_domain_env = "bar.com" - - assert ( - SubscriptionsServiceClient._get_universe_domain( - client_universe_domain, universe_domain_env - ) - == client_universe_domain - ) - assert ( - SubscriptionsServiceClient._get_universe_domain(None, universe_domain_env) - == universe_domain_env - ) - assert ( - SubscriptionsServiceClient._get_universe_domain(None, None) - == SubscriptionsServiceClient._DEFAULT_UNIVERSE - ) - - with pytest.raises(ValueError) as excinfo: - SubscriptionsServiceClient._get_universe_domain("", None) - assert str(excinfo.value) == "Universe Domain cannot be an empty string." - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceGrpcTransport, - "grpc", - ), - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceRestTransport, - "rest", - ), - ], -) -def test__validate_universe_domain(client_class, transport_class, transport_name): - client = client_class( - transport=transport_class(credentials=ga_credentials.AnonymousCredentials()) - ) - assert client._validate_universe_domain() == True - - # Test the case when universe is already validated. - assert client._validate_universe_domain() == True - - if transport_name == "grpc": - # Test the case where credentials are provided by the - # `local_channel_credentials`. The default universes in both match. - channel = grpc.secure_channel( - "http://localhost/", grpc.local_channel_credentials() - ) - client = client_class(transport=transport_class(channel=channel)) - assert client._validate_universe_domain() == True - - # Test the case where credentials do not exist: e.g. a transport is provided - # with no credentials. Validation should still succeed because there is no - # mismatch with non-existent credentials. - channel = grpc.secure_channel( - "http://localhost/", grpc.local_channel_credentials() - ) - transport = transport_class(channel=channel) - transport._credentials = None - client = client_class(transport=transport) - assert client._validate_universe_domain() == True - - # TODO: This is needed to cater for older versions of google-auth - # Make this test unconditional once the minimum supported version of - # google-auth becomes 2.23.0 or higher. - google_auth_major, google_auth_minor = [ - int(part) for part in google.auth.__version__.split(".")[0:2] - ] - if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): - credentials = ga_credentials.AnonymousCredentials() - credentials._universe_domain = "foo.com" - # Test the case when there is a universe mismatch from the credentials. - client = client_class(transport=transport_class(credentials=credentials)) - with pytest.raises(ValueError) as excinfo: - client._validate_universe_domain() - assert ( - str(excinfo.value) - == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." - ) - - # Test the case when there is a universe mismatch from the client. - # - # TODO: Make this test unconditional once the minimum supported version of - # google-api-core becomes 2.15.0 or higher. - api_core_major, api_core_minor = [ - int(part) for part in api_core_version.__version__.split(".")[0:2] - ] - if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): - client = client_class( - client_options={"universe_domain": "bar.com"}, - transport=transport_class( - credentials=ga_credentials.AnonymousCredentials(), - ), - ) - with pytest.raises(ValueError) as excinfo: - client._validate_universe_domain() - assert ( - str(excinfo.value) - == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." - ) - - # Test that ValueError is raised if universe_domain is provided via client options and credentials is None - with pytest.raises(ValueError): - client._compare_universes("foo.bar", None) - - -@pytest.mark.parametrize( - "client_class,transport_name", - [ - (SubscriptionsServiceClient, "grpc"), - (SubscriptionsServiceAsyncClient, "grpc_asyncio"), - (SubscriptionsServiceClient, "rest"), - ], -) -def test_subscriptions_service_client_from_service_account_info( - client_class, transport_name -): - creds = ga_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, transport=transport_name) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - "workspaceevents.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://workspaceevents.googleapis.com" - ) - - -@pytest.mark.parametrize( - "transport_class,transport_name", - [ - (transports.SubscriptionsServiceGrpcTransport, "grpc"), - (transports.SubscriptionsServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.SubscriptionsServiceRestTransport, "rest"), - ], -) -def test_subscriptions_service_client_service_account_always_use_jwt( - transport_class, transport_name -): - with mock.patch.object( - service_account.Credentials, "with_always_use_jwt_access", create=True - ) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object( - service_account.Credentials, "with_always_use_jwt_access", create=True - ) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize( - "client_class,transport_name", - [ - (SubscriptionsServiceClient, "grpc"), - (SubscriptionsServiceAsyncClient, "grpc_asyncio"), - (SubscriptionsServiceClient, "rest"), - ], -) -def test_subscriptions_service_client_from_service_account_file( - client_class, transport_name -): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object( - service_account.Credentials, "from_service_account_file" - ) as factory: - factory.return_value = creds - client = client_class.from_service_account_file( - "dummy/file/path.json", transport=transport_name - ) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json( - "dummy/file/path.json", transport=transport_name - ) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - "workspaceevents.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://workspaceevents.googleapis.com" - ) - - -def test_subscriptions_service_client_get_transport_class(): - transport = SubscriptionsServiceClient.get_transport_class() - available_transports = [ - transports.SubscriptionsServiceGrpcTransport, - transports.SubscriptionsServiceRestTransport, - ] - assert transport in available_transports - - transport = SubscriptionsServiceClient.get_transport_class("grpc") - assert transport == transports.SubscriptionsServiceGrpcTransport - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceGrpcTransport, - "grpc", - ), - ( - SubscriptionsServiceAsyncClient, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - ), - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceRestTransport, - "rest", - ), - ], -) -@mock.patch.object( - SubscriptionsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(SubscriptionsServiceClient), -) -@mock.patch.object( - SubscriptionsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(SubscriptionsServiceAsyncClient), -) -def test_subscriptions_service_client_client_options( - client_class, transport_class, transport_name -): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(SubscriptionsServiceClient, "get_transport_class") as gtc: - transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(SubscriptionsServiceClient, "get_transport_class") as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client = client_class(transport=transport_name) - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError) as excinfo: - client = client_class(transport=transport_name) - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - # Check the case api_endpoint is provided - options = client_options.ClientOptions( - api_audience="https://language.googleapis.com" - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience="https://language.googleapis.com", - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceGrpcTransport, - "grpc", - "true", - ), - ( - SubscriptionsServiceAsyncClient, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceGrpcTransport, - "grpc", - "false", - ), - ( - SubscriptionsServiceAsyncClient, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceRestTransport, - "rest", - "true", - ), - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceRestTransport, - "rest", - "false", - ), - ], -) -@mock.patch.object( - SubscriptionsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(SubscriptionsServiceClient), -) -@mock.patch.object( - SubscriptionsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(SubscriptionsServiceAsyncClient), -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_subscriptions_service_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - options = client_options.ClientOptions( - client_cert_source=client_cert_source_callback - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ) - 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, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - 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=True, - ): - with mock.patch( - "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_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ) - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - 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, - always_use_jwt_access=True, - api_audience=None, - ) - - # 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(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class", [SubscriptionsServiceClient, SubscriptionsServiceAsyncClient] -) -@mock.patch.object( - SubscriptionsServiceClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(SubscriptionsServiceClient), -) -@mock.patch.object( - SubscriptionsServiceAsyncClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(SubscriptionsServiceAsyncClient), -) -def test_subscriptions_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, - ): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=mock_client_cert_source, - ): - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - - -@pytest.mark.parametrize( - "client_class", [SubscriptionsServiceClient, SubscriptionsServiceAsyncClient] -) -@mock.patch.object( - SubscriptionsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(SubscriptionsServiceClient), -) -@mock.patch.object( - SubscriptionsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(SubscriptionsServiceAsyncClient), -) -def test_subscriptions_service_client_client_api_endpoint(client_class): - mock_client_cert_source = client_cert_source_callback - api_override = "foo.com" - default_universe = SubscriptionsServiceClient._DEFAULT_UNIVERSE - default_endpoint = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=default_universe - ) - mock_universe = "bar.com" - mock_endpoint = SubscriptionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=mock_universe - ) - - # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", - # use ClientOptions.api_endpoint as the api endpoint regardless. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" - ): - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=api_override - ) - client = client_class( - client_options=options, - credentials=ga_credentials.AnonymousCredentials(), - ) - assert client.api_endpoint == api_override - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", - # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - - # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), - # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, - # and ClientOptions.universe_domain="bar.com", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. - options = client_options.ClientOptions() - universe_exists = hasattr(options, "universe_domain") - if universe_exists: - options = client_options.ClientOptions(universe_domain=mock_universe) - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - else: - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - assert client.api_endpoint == ( - mock_endpoint if universe_exists else default_endpoint - ) - assert client.universe_domain == ( - mock_universe if universe_exists else default_universe - ) - - # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - options = client_options.ClientOptions() - if hasattr(options, "universe_domain"): - delattr(options, "universe_domain") - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - assert client.api_endpoint == default_endpoint - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceGrpcTransport, - "grpc", - ), - ( - SubscriptionsServiceAsyncClient, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - ), - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceRestTransport, - "rest", - ), - ], -) -def test_subscriptions_service_client_client_options_scopes( - client_class, transport_class, transport_name -): - # Check the case scopes are provided. - options = client_options.ClientOptions( - scopes=["1", "2"], - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,grpc_helpers", - [ - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceGrpcTransport, - "grpc", - grpc_helpers, - ), - ( - SubscriptionsServiceAsyncClient, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - grpc_helpers_async, - ), - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceRestTransport, - "rest", - None, - ), - ], -) -def test_subscriptions_service_client_client_options_credentials_file( - client_class, transport_class, transport_name, grpc_helpers -): - # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") - - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -def test_subscriptions_service_client_client_options_from_dict(): - with mock.patch( - "google.apps.events_subscriptions_v1.services.subscriptions_service.transports.SubscriptionsServiceGrpcTransport.__init__" - ) as grpc_transport: - grpc_transport.return_value = None - client = SubscriptionsServiceClient( - client_options={"api_endpoint": "squid.clam.whelk"} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,grpc_helpers", - [ - ( - SubscriptionsServiceClient, - transports.SubscriptionsServiceGrpcTransport, - "grpc", - grpc_helpers, - ), - ( - SubscriptionsServiceAsyncClient, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - grpc_helpers_async, - ), - ], -) -def test_subscriptions_service_client_create_channel_credentials_file( - client_class, transport_class, transport_name, grpc_helpers -): - # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") - - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # test that the credentials from file are saved and used as the credentials. - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel" - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - file_creds = ga_credentials.AnonymousCredentials() - load_creds.return_value = (file_creds, None) - adc.return_value = (creds, None) - client = client_class(client_options=options, transport=transport_name) - create_channel.assert_called_with( - "workspaceevents.googleapis.com:443", - credentials=file_creds, - credentials_file=None, - quota_project_id=None, - default_scopes=( - "https://www.googleapis.com/auth/chat.bot", - "https://www.googleapis.com/auth/chat.memberships", - "https://www.googleapis.com/auth/chat.memberships.readonly", - "https://www.googleapis.com/auth/chat.messages", - "https://www.googleapis.com/auth/chat.messages.reactions", - "https://www.googleapis.com/auth/chat.messages.reactions.readonly", - "https://www.googleapis.com/auth/chat.messages.readonly", - "https://www.googleapis.com/auth/chat.spaces", - "https://www.googleapis.com/auth/chat.spaces.readonly", - "https://www.googleapis.com/auth/meetings.space.created", - "https://www.googleapis.com/auth/meetings.space.readonly", - ), - scopes=None, - default_host="workspaceevents.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.CreateSubscriptionRequest, - dict, - ], -) -def test_create_subscription(request_type, transport: str = "grpc"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.create_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.CreateSubscriptionRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -def test_create_subscription_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 = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_subscription), "__call__" - ) as call: - client.create_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.CreateSubscriptionRequest() - - -@pytest.mark.asyncio -async def test_create_subscription_async( - transport: str = "grpc_asyncio", - request_type=subscriptions_service.CreateSubscriptionRequest, -): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - response = await client.create_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.CreateSubscriptionRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_create_subscription_async_from_dict(): - await test_create_subscription_async(request_type=dict) - - -def test_create_subscription_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.create_subscription( - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].subscription - mock_val = subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ) - assert arg == mock_val - - -def test_create_subscription_flattened_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_subscription( - subscriptions_service.CreateSubscriptionRequest(), - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - - -@pytest.mark.asyncio -async def test_create_subscription_flattened_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/op") - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.create_subscription( - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].subscription - mock_val = subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ) - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_create_subscription_flattened_error_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.create_subscription( - subscriptions_service.CreateSubscriptionRequest(), - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.DeleteSubscriptionRequest, - dict, - ], -) -def test_delete_subscription(request_type, transport: str = "grpc"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.delete_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.DeleteSubscriptionRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -def test_delete_subscription_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 = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_subscription), "__call__" - ) as call: - client.delete_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.DeleteSubscriptionRequest() - - -@pytest.mark.asyncio -async def test_delete_subscription_async( - transport: str = "grpc_asyncio", - request_type=subscriptions_service.DeleteSubscriptionRequest, -): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - response = await client.delete_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.DeleteSubscriptionRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_delete_subscription_async_from_dict(): - await test_delete_subscription_async(request_type=dict) - - -def test_delete_subscription_field_headers(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = subscriptions_service.DeleteSubscriptionRequest() - - request.name = "name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_subscription), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.delete_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name_value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_delete_subscription_field_headers_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = subscriptions_service.DeleteSubscriptionRequest() - - request.name = "name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_subscription), "__call__" - ) as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/op") - ) - await client.delete_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name_value", - ) in kw["metadata"] - - -def test_delete_subscription_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.delete_subscription( - name="name_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = "name_value" - assert arg == mock_val - - -def test_delete_subscription_flattened_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_subscription( - subscriptions_service.DeleteSubscriptionRequest(), - name="name_value", - ) - - -@pytest.mark.asyncio -async def test_delete_subscription_flattened_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/op") - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.delete_subscription( - name="name_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = "name_value" - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_delete_subscription_flattened_error_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.delete_subscription( - subscriptions_service.DeleteSubscriptionRequest(), - name="name_value", - ) - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.GetSubscriptionRequest, - dict, - ], -) -def test_get_subscription(request_type, transport: str = "grpc"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = subscription_resource.Subscription( - name="name_value", - uid="uid_value", - target_resource="target_resource_value", - event_types=["event_types_value"], - state=subscription_resource.Subscription.State.ACTIVE, - suspension_reason=subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED, - authority="authority_value", - reconciling=True, - etag="etag_value", - ) - response = client.get_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.GetSubscriptionRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, subscription_resource.Subscription) - assert response.name == "name_value" - assert response.uid == "uid_value" - assert response.target_resource == "target_resource_value" - assert response.event_types == ["event_types_value"] - assert response.state == subscription_resource.Subscription.State.ACTIVE - assert ( - response.suspension_reason - == subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED - ) - assert response.authority == "authority_value" - assert response.reconciling is True - assert response.etag == "etag_value" - - -def test_get_subscription_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 = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: - client.get_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.GetSubscriptionRequest() - - -@pytest.mark.asyncio -async def test_get_subscription_async( - transport: str = "grpc_asyncio", - request_type=subscriptions_service.GetSubscriptionRequest, -): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - subscription_resource.Subscription( - name="name_value", - uid="uid_value", - target_resource="target_resource_value", - event_types=["event_types_value"], - state=subscription_resource.Subscription.State.ACTIVE, - suspension_reason=subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED, - authority="authority_value", - reconciling=True, - etag="etag_value", - ) - ) - response = await client.get_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.GetSubscriptionRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, subscription_resource.Subscription) - assert response.name == "name_value" - assert response.uid == "uid_value" - assert response.target_resource == "target_resource_value" - assert response.event_types == ["event_types_value"] - assert response.state == subscription_resource.Subscription.State.ACTIVE - assert ( - response.suspension_reason - == subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED - ) - assert response.authority == "authority_value" - assert response.reconciling is True - assert response.etag == "etag_value" - - -@pytest.mark.asyncio -async def test_get_subscription_async_from_dict(): - await test_get_subscription_async(request_type=dict) - - -def test_get_subscription_field_headers(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = subscriptions_service.GetSubscriptionRequest() - - request.name = "name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: - call.return_value = subscription_resource.Subscription() - client.get_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name_value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_get_subscription_field_headers_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = subscriptions_service.GetSubscriptionRequest() - - request.name = "name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - subscription_resource.Subscription() - ) - await client.get_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name_value", - ) in kw["metadata"] - - -def test_get_subscription_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = subscription_resource.Subscription() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.get_subscription( - name="name_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = "name_value" - assert arg == mock_val - - -def test_get_subscription_flattened_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_subscription( - subscriptions_service.GetSubscriptionRequest(), - name="name_value", - ) - - -@pytest.mark.asyncio -async def test_get_subscription_flattened_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_subscription), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = subscription_resource.Subscription() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - subscription_resource.Subscription() - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.get_subscription( - name="name_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = "name_value" - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_get_subscription_flattened_error_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.get_subscription( - subscriptions_service.GetSubscriptionRequest(), - name="name_value", - ) - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.ListSubscriptionsRequest, - dict, - ], -) -def test_list_subscriptions(request_type, transport: str = "grpc"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_subscriptions), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = subscriptions_service.ListSubscriptionsResponse( - next_page_token="next_page_token_value", - ) - response = client.list_subscriptions(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.ListSubscriptionsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListSubscriptionsPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_subscriptions_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 = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_subscriptions), "__call__" - ) as call: - client.list_subscriptions() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.ListSubscriptionsRequest() - - -@pytest.mark.asyncio -async def test_list_subscriptions_async( - transport: str = "grpc_asyncio", - request_type=subscriptions_service.ListSubscriptionsRequest, -): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_subscriptions), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - subscriptions_service.ListSubscriptionsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_subscriptions(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.ListSubscriptionsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListSubscriptionsAsyncPager) - assert response.next_page_token == "next_page_token_value" - - -@pytest.mark.asyncio -async def test_list_subscriptions_async_from_dict(): - await test_list_subscriptions_async(request_type=dict) - - -def test_list_subscriptions_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_subscriptions), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = subscriptions_service.ListSubscriptionsResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.list_subscriptions( - page_size=951, - page_token="page_token_value", - filter="filter_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].page_size - mock_val = 951 - assert arg == mock_val - arg = args[0].page_token - mock_val = "page_token_value" - assert arg == mock_val - arg = args[0].filter - mock_val = "filter_value" - assert arg == mock_val - - -def test_list_subscriptions_flattened_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_subscriptions( - subscriptions_service.ListSubscriptionsRequest(), - page_size=951, - page_token="page_token_value", - filter="filter_value", - ) - - -@pytest.mark.asyncio -async def test_list_subscriptions_flattened_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_subscriptions), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = subscriptions_service.ListSubscriptionsResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - subscriptions_service.ListSubscriptionsResponse() - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.list_subscriptions( - page_size=951, - page_token="page_token_value", - filter="filter_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].page_size - mock_val = 951 - assert arg == mock_val - arg = args[0].page_token - mock_val = "page_token_value" - assert arg == mock_val - arg = args[0].filter - mock_val = "filter_value" - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_list_subscriptions_flattened_error_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.list_subscriptions( - subscriptions_service.ListSubscriptionsRequest(), - page_size=951, - page_token="page_token_value", - filter="filter_value", - ) - - -def test_list_subscriptions_pager(transport_name: str = "grpc"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_subscriptions), "__call__" - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - subscription_resource.Subscription(), - subscription_resource.Subscription(), - ], - next_page_token="abc", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[], - next_page_token="def", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - ], - next_page_token="ghi", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - subscription_resource.Subscription(), - ], - ), - RuntimeError, - ) - - metadata = () - pager = client.list_subscriptions(request={}) - - assert pager._metadata == metadata - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, subscription_resource.Subscription) for i in results) - - -def test_list_subscriptions_pages(transport_name: str = "grpc"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_subscriptions), "__call__" - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - subscription_resource.Subscription(), - subscription_resource.Subscription(), - ], - next_page_token="abc", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[], - next_page_token="def", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - ], - next_page_token="ghi", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - subscription_resource.Subscription(), - ], - ), - RuntimeError, - ) - pages = list(client.list_subscriptions(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -@pytest.mark.asyncio -async def test_list_subscriptions_async_pager(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_subscriptions), - "__call__", - new_callable=mock.AsyncMock, - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - subscription_resource.Subscription(), - subscription_resource.Subscription(), - ], - next_page_token="abc", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[], - next_page_token="def", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - ], - next_page_token="ghi", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - subscription_resource.Subscription(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_subscriptions( - request={}, - ) - assert async_pager.next_page_token == "abc" - responses = [] - async for response in async_pager: # pragma: no branch - responses.append(response) - - assert len(responses) == 6 - assert all(isinstance(i, subscription_resource.Subscription) for i in responses) - - -@pytest.mark.asyncio -async def test_list_subscriptions_async_pages(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_subscriptions), - "__call__", - new_callable=mock.AsyncMock, - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - subscription_resource.Subscription(), - subscription_resource.Subscription(), - ], - next_page_token="abc", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[], - next_page_token="def", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - ], - next_page_token="ghi", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - subscription_resource.Subscription(), - ], - ), - RuntimeError, - ) - pages = [] - # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` - # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 - async for page_ in ( # pragma: no branch - await client.list_subscriptions(request={}) - ).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.UpdateSubscriptionRequest, - dict, - ], -) -def test_update_subscription(request_type, transport: str = "grpc"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.update_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.UpdateSubscriptionRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -def test_update_subscription_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 = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_subscription), "__call__" - ) as call: - client.update_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.UpdateSubscriptionRequest() - - -@pytest.mark.asyncio -async def test_update_subscription_async( - transport: str = "grpc_asyncio", - request_type=subscriptions_service.UpdateSubscriptionRequest, -): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - response = await client.update_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.UpdateSubscriptionRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_update_subscription_async_from_dict(): - await test_update_subscription_async(request_type=dict) - - -def test_update_subscription_field_headers(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = subscriptions_service.UpdateSubscriptionRequest() - - request.subscription.name = "name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_subscription), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.update_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "subscription.name=name_value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_update_subscription_field_headers_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = subscriptions_service.UpdateSubscriptionRequest() - - request.subscription.name = "name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_subscription), "__call__" - ) as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/op") - ) - await client.update_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "subscription.name=name_value", - ) in kw["metadata"] - - -def test_update_subscription_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.update_subscription( - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].subscription - mock_val = subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ) - assert arg == mock_val - arg = args[0].update_mask - mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) - assert arg == mock_val - - -def test_update_subscription_flattened_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_subscription( - subscriptions_service.UpdateSubscriptionRequest(), - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - - -@pytest.mark.asyncio -async def test_update_subscription_flattened_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/op") - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.update_subscription( - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].subscription - mock_val = subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ) - assert arg == mock_val - arg = args[0].update_mask - mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_update_subscription_flattened_error_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.update_subscription( - subscriptions_service.UpdateSubscriptionRequest(), - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.ReactivateSubscriptionRequest, - dict, - ], -) -def test_reactivate_subscription(request_type, transport: str = "grpc"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.reactivate_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.reactivate_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.ReactivateSubscriptionRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -def test_reactivate_subscription_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 = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.reactivate_subscription), "__call__" - ) as call: - client.reactivate_subscription() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.ReactivateSubscriptionRequest() - - -@pytest.mark.asyncio -async def test_reactivate_subscription_async( - transport: str = "grpc_asyncio", - request_type=subscriptions_service.ReactivateSubscriptionRequest, -): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.reactivate_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - response = await client.reactivate_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == subscriptions_service.ReactivateSubscriptionRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, future.Future) - - -@pytest.mark.asyncio -async def test_reactivate_subscription_async_from_dict(): - await test_reactivate_subscription_async(request_type=dict) - - -def test_reactivate_subscription_field_headers(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = subscriptions_service.ReactivateSubscriptionRequest() - - request.name = "name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.reactivate_subscription), "__call__" - ) as call: - call.return_value = operations_pb2.Operation(name="operations/op") - client.reactivate_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name_value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_reactivate_subscription_field_headers_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = subscriptions_service.ReactivateSubscriptionRequest() - - request.name = "name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.reactivate_subscription), "__call__" - ) as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/op") - ) - await client.reactivate_subscription(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name_value", - ) in kw["metadata"] - - -def test_reactivate_subscription_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.reactivate_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.reactivate_subscription( - name="name_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = "name_value" - assert arg == mock_val - - -def test_reactivate_subscription_flattened_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.reactivate_subscription( - subscriptions_service.ReactivateSubscriptionRequest(), - name="name_value", - ) - - -@pytest.mark.asyncio -async def test_reactivate_subscription_flattened_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.reactivate_subscription), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation(name="operations/op") - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation(name="operations/spam") - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.reactivate_subscription( - name="name_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = "name_value" - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_reactivate_subscription_flattened_error_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.reactivate_subscription( - subscriptions_service.ReactivateSubscriptionRequest(), - name="name_value", - ) - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.CreateSubscriptionRequest, - dict, - ], -) -def test_create_subscription_rest(request_type): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request_init["subscription"] = { - "expire_time": {"seconds": 751, "nanos": 543}, - "ttl": {"seconds": 751, "nanos": 543}, - "name": "name_value", - "uid": "uid_value", - "target_resource": "target_resource_value", - "event_types": ["event_types_value1", "event_types_value2"], - "payload_options": { - "include_resource": True, - "field_mask": {"paths": ["paths_value1", "paths_value2"]}, - }, - "notification_endpoint": {"pubsub_topic": "pubsub_topic_value"}, - "state": 1, - "suspension_reason": 1, - "authority": "authority_value", - "create_time": {}, - "update_time": {}, - "reconciling": True, - "etag": "etag_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = subscriptions_service.CreateSubscriptionRequest.meta.fields[ - "subscription" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["subscription"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["subscription"][field])): - del request_init["subscription"][field][i][subfield] - else: - del request_init["subscription"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_subscription(request) - - # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" - - -def test_create_subscription_rest_required_fields( - request_type=subscriptions_service.CreateSubscriptionRequest, -): - transport_class = transports.SubscriptionsServiceRestTransport - - request_init = {} - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_subscription._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_subscription._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("validate_only",)) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.create_subscription(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_create_subscription_rest_unset_required_fields(): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.create_subscription._get_unset_required_fields({}) - assert set(unset_fields) == (set(("validateOnly",)) & set(("subscription",))) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_subscription_rest_interceptors(null_interceptor): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.SubscriptionsServiceRestInterceptor(), - ) - client = SubscriptionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "post_create_subscription" - ) as post, mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "pre_create_subscription" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = subscriptions_service.CreateSubscriptionRequest.pb( - subscriptions_service.CreateSubscriptionRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) - - request = subscriptions_service.CreateSubscriptionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - - client.create_subscription( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_create_subscription_rest_bad_request( - transport: str = "rest", - request_type=subscriptions_service.CreateSubscriptionRequest, -): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_subscription(request) - - -def test_create_subscription_rest_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {} - - # get truthy value for each flattened field - mock_args = dict( - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.create_subscription(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/subscriptions" % client.transport._host, args[1] - ) - - -def test_create_subscription_rest_flattened_error(transport: str = "rest"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_subscription( - subscriptions_service.CreateSubscriptionRequest(), - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - - -def test_create_subscription_rest_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.DeleteSubscriptionRequest, - dict, - ], -) -def test_delete_subscription_rest(request_type): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "subscriptions/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_subscription(request) - - # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" - - -def test_delete_subscription_rest_required_fields( - request_type=subscriptions_service.DeleteSubscriptionRequest, -): - transport_class = transports.SubscriptionsServiceRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_subscription._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_subscription._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "allow_missing", - "etag", - "validate_only", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.delete_subscription(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_delete_subscription_rest_unset_required_fields(): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.delete_subscription._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "allowMissing", - "etag", - "validateOnly", - ) - ) - & set(("name",)) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_subscription_rest_interceptors(null_interceptor): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.SubscriptionsServiceRestInterceptor(), - ) - client = SubscriptionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "post_delete_subscription" - ) as post, mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "pre_delete_subscription" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = subscriptions_service.DeleteSubscriptionRequest.pb( - subscriptions_service.DeleteSubscriptionRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) - - request = subscriptions_service.DeleteSubscriptionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - - client.delete_subscription( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_delete_subscription_rest_bad_request( - transport: str = "rest", - request_type=subscriptions_service.DeleteSubscriptionRequest, -): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "subscriptions/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_subscription(request) - - -def test_delete_subscription_rest_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "subscriptions/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.delete_subscription(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=subscriptions/*}" % client.transport._host, args[1] - ) - - -def test_delete_subscription_rest_flattened_error(transport: str = "rest"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_subscription( - subscriptions_service.DeleteSubscriptionRequest(), - name="name_value", - ) - - -def test_delete_subscription_rest_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.GetSubscriptionRequest, - dict, - ], -) -def test_get_subscription_rest(request_type): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "subscriptions/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = subscription_resource.Subscription( - name="name_value", - uid="uid_value", - target_resource="target_resource_value", - event_types=["event_types_value"], - state=subscription_resource.Subscription.State.ACTIVE, - suspension_reason=subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED, - authority="authority_value", - reconciling=True, - etag="etag_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = subscription_resource.Subscription.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_subscription(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, subscription_resource.Subscription) - assert response.name == "name_value" - assert response.uid == "uid_value" - assert response.target_resource == "target_resource_value" - assert response.event_types == ["event_types_value"] - assert response.state == subscription_resource.Subscription.State.ACTIVE - assert ( - response.suspension_reason - == subscription_resource.Subscription.ErrorType.USER_SCOPE_REVOKED - ) - assert response.authority == "authority_value" - assert response.reconciling is True - assert response.etag == "etag_value" - - -def test_get_subscription_rest_required_fields( - request_type=subscriptions_service.GetSubscriptionRequest, -): - transport_class = transports.SubscriptionsServiceRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_subscription._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_subscription._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = subscription_resource.Subscription() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = subscription_resource.Subscription.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.get_subscription(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_get_subscription_rest_unset_required_fields(): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.get_subscription._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_subscription_rest_interceptors(null_interceptor): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.SubscriptionsServiceRestInterceptor(), - ) - client = SubscriptionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "post_get_subscription" - ) as post, mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "pre_get_subscription" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = subscriptions_service.GetSubscriptionRequest.pb( - subscriptions_service.GetSubscriptionRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = subscription_resource.Subscription.to_json( - subscription_resource.Subscription() - ) - - request = subscriptions_service.GetSubscriptionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = subscription_resource.Subscription() - - client.get_subscription( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_subscription_rest_bad_request( - transport: str = "rest", request_type=subscriptions_service.GetSubscriptionRequest -): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "subscriptions/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_subscription(request) - - -def test_get_subscription_rest_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = subscription_resource.Subscription() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "subscriptions/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = subscription_resource.Subscription.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.get_subscription(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=subscriptions/*}" % client.transport._host, args[1] - ) - - -def test_get_subscription_rest_flattened_error(transport: str = "rest"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_subscription( - subscriptions_service.GetSubscriptionRequest(), - name="name_value", - ) - - -def test_get_subscription_rest_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.ListSubscriptionsRequest, - dict, - ], -) -def test_list_subscriptions_rest(request_type): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = subscriptions_service.ListSubscriptionsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = subscriptions_service.ListSubscriptionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_subscriptions(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListSubscriptionsPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_subscriptions_rest_required_fields( - request_type=subscriptions_service.ListSubscriptionsRequest, -): - transport_class = transports.SubscriptionsServiceRestTransport - - request_init = {} - request_init["filter"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - assert "filter" not in jsonified_request - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_subscriptions._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - assert "filter" in jsonified_request - assert jsonified_request["filter"] == request_init["filter"] - - jsonified_request["filter"] = "filter_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_subscriptions._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "filter" in jsonified_request - assert jsonified_request["filter"] == "filter_value" - - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = subscriptions_service.ListSubscriptionsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = subscriptions_service.ListSubscriptionsResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.list_subscriptions(request) - - expected_params = [ - ( - "filter", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_list_subscriptions_rest_unset_required_fields(): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.list_subscriptions._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) - ) - & set(("filter",)) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_subscriptions_rest_interceptors(null_interceptor): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.SubscriptionsServiceRestInterceptor(), - ) - client = SubscriptionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "post_list_subscriptions" - ) as post, mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "pre_list_subscriptions" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = subscriptions_service.ListSubscriptionsRequest.pb( - subscriptions_service.ListSubscriptionsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = ( - subscriptions_service.ListSubscriptionsResponse.to_json( - subscriptions_service.ListSubscriptionsResponse() - ) - ) - - request = subscriptions_service.ListSubscriptionsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = subscriptions_service.ListSubscriptionsResponse() - - client.list_subscriptions( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_subscriptions_rest_bad_request( - transport: str = "rest", request_type=subscriptions_service.ListSubscriptionsRequest -): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_subscriptions(request) - - -def test_list_subscriptions_rest_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = subscriptions_service.ListSubscriptionsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {} - - # get truthy value for each flattened field - mock_args = dict( - page_size=951, - page_token="page_token_value", - filter="filter_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = subscriptions_service.ListSubscriptionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.list_subscriptions(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/subscriptions" % client.transport._host, args[1] - ) - - -def test_list_subscriptions_rest_flattened_error(transport: str = "rest"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_subscriptions( - subscriptions_service.ListSubscriptionsRequest(), - page_size=951, - page_token="page_token_value", - filter="filter_value", - ) - - -def test_list_subscriptions_rest_pager(transport: str = "rest"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - subscription_resource.Subscription(), - subscription_resource.Subscription(), - ], - next_page_token="abc", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[], - next_page_token="def", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - ], - next_page_token="ghi", - ), - subscriptions_service.ListSubscriptionsResponse( - subscriptions=[ - subscription_resource.Subscription(), - subscription_resource.Subscription(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - subscriptions_service.ListSubscriptionsResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {} - - pager = client.list_subscriptions(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, subscription_resource.Subscription) for i in results) - - pages = list(client.list_subscriptions(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.UpdateSubscriptionRequest, - dict, - ], -) -def test_update_subscription_rest(request_type): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"subscription": {"name": "subscriptions/sample1"}} - request_init["subscription"] = { - "expire_time": {"seconds": 751, "nanos": 543}, - "ttl": {"seconds": 751, "nanos": 543}, - "name": "subscriptions/sample1", - "uid": "uid_value", - "target_resource": "target_resource_value", - "event_types": ["event_types_value1", "event_types_value2"], - "payload_options": { - "include_resource": True, - "field_mask": {"paths": ["paths_value1", "paths_value2"]}, - }, - "notification_endpoint": {"pubsub_topic": "pubsub_topic_value"}, - "state": 1, - "suspension_reason": 1, - "authority": "authority_value", - "create_time": {}, - "update_time": {}, - "reconciling": True, - "etag": "etag_value", - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = subscriptions_service.UpdateSubscriptionRequest.meta.fields[ - "subscription" - ] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["subscription"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["subscription"][field])): - del request_init["subscription"][field][i][subfield] - else: - del request_init["subscription"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_subscription(request) - - # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" - - -def test_update_subscription_rest_required_fields( - request_type=subscriptions_service.UpdateSubscriptionRequest, -): - transport_class = transports.SubscriptionsServiceRestTransport - - request_init = {} - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_subscription._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_subscription._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "update_mask", - "validate_only", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "patch", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.update_subscription(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_update_subscription_rest_unset_required_fields(): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.update_subscription._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "updateMask", - "validateOnly", - ) - ) - & set(("subscription",)) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_subscription_rest_interceptors(null_interceptor): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.SubscriptionsServiceRestInterceptor(), - ) - client = SubscriptionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "post_update_subscription" - ) as post, mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "pre_update_subscription" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = subscriptions_service.UpdateSubscriptionRequest.pb( - subscriptions_service.UpdateSubscriptionRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) - - request = subscriptions_service.UpdateSubscriptionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - - client.update_subscription( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_subscription_rest_bad_request( - transport: str = "rest", - request_type=subscriptions_service.UpdateSubscriptionRequest, -): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"subscription": {"name": "subscriptions/sample1"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_subscription(request) - - -def test_update_subscription_rest_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {"subscription": {"name": "subscriptions/sample1"}} - - # get truthy value for each flattened field - mock_args = dict( - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.update_subscription(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{subscription.name=subscriptions/*}" % client.transport._host, - args[1], - ) - - -def test_update_subscription_rest_flattened_error(transport: str = "rest"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_subscription( - subscriptions_service.UpdateSubscriptionRequest(), - subscription=subscription_resource.Subscription( - expire_time=timestamp_pb2.Timestamp(seconds=751) - ), - update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), - ) - - -def test_update_subscription_rest_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - subscriptions_service.ReactivateSubscriptionRequest, - dict, - ], -) -def test_reactivate_subscription_rest(request_type): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "subscriptions/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.reactivate_subscription(request) - - # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" - - -def test_reactivate_subscription_rest_required_fields( - request_type=subscriptions_service.ReactivateSubscriptionRequest, -): - transport_class = transports.SubscriptionsServiceRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).reactivate_subscription._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).reactivate_subscription._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.reactivate_subscription(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_reactivate_subscription_rest_unset_required_fields(): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.reactivate_subscription._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_reactivate_subscription_rest_interceptors(null_interceptor): - transport = transports.SubscriptionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.SubscriptionsServiceRestInterceptor(), - ) - client = SubscriptionsServiceClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "post_reactivate_subscription" - ) as post, mock.patch.object( - transports.SubscriptionsServiceRestInterceptor, "pre_reactivate_subscription" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = subscriptions_service.ReactivateSubscriptionRequest.pb( - subscriptions_service.ReactivateSubscriptionRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) - - request = subscriptions_service.ReactivateSubscriptionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - - client.reactivate_subscription( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_reactivate_subscription_rest_bad_request( - transport: str = "rest", - request_type=subscriptions_service.ReactivateSubscriptionRequest, -): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "subscriptions/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.reactivate_subscription(request) - - -def test_reactivate_subscription_rest_flattened(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "subscriptions/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.reactivate_subscription(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=subscriptions/*}:reactivate" % client.transport._host, args[1] - ) - - -def test_reactivate_subscription_rest_flattened_error(transport: str = "rest"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.reactivate_subscription( - subscriptions_service.ReactivateSubscriptionRequest(), - name="name_value", - ) - - -def test_reactivate_subscription_rest_error(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.SubscriptionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.SubscriptionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = SubscriptionsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.SubscriptionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = SubscriptionsServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = SubscriptionsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.SubscriptionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = SubscriptionsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.SubscriptionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = SubscriptionsServiceClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.SubscriptionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.SubscriptionsServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.SubscriptionsServiceGrpcTransport, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - transports.SubscriptionsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = SubscriptionsServiceClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.SubscriptionsServiceGrpcTransport, - ) - - -def test_subscriptions_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.SubscriptionsServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json", - ) - - -def test_subscriptions_service_base_transport(): - # Instantiate the base transport. - with mock.patch( - "google.apps.events_subscriptions_v1.services.subscriptions_service.transports.SubscriptionsServiceTransport.__init__" - ) as Transport: - Transport.return_value = None - transport = transports.SubscriptionsServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - "create_subscription", - "delete_subscription", - "get_subscription", - "list_subscriptions", - "update_subscription", - "reactivate_subscription", - "get_operation", - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - # Additionally, the LRO client (a property) should - # also raise NotImplementedError - with pytest.raises(NotImplementedError): - transport.operations_client - - # Catch all for all remaining methods and properties - remainder = [ - "kind", - ] - for r in remainder: - with pytest.raises(NotImplementedError): - getattr(transport, r)() - - -def test_subscriptions_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.apps.events_subscriptions_v1.services.subscriptions_service.transports.SubscriptionsServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.SubscriptionsServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=None, - default_scopes=( - "https://www.googleapis.com/auth/chat.bot", - "https://www.googleapis.com/auth/chat.memberships", - "https://www.googleapis.com/auth/chat.memberships.readonly", - "https://www.googleapis.com/auth/chat.messages", - "https://www.googleapis.com/auth/chat.messages.reactions", - "https://www.googleapis.com/auth/chat.messages.reactions.readonly", - "https://www.googleapis.com/auth/chat.messages.readonly", - "https://www.googleapis.com/auth/chat.spaces", - "https://www.googleapis.com/auth/chat.spaces.readonly", - "https://www.googleapis.com/auth/meetings.space.created", - "https://www.googleapis.com/auth/meetings.space.readonly", - ), - quota_project_id="octopus", - ) - - -def test_subscriptions_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( - "google.apps.events_subscriptions_v1.services.subscriptions_service.transports.SubscriptionsServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.SubscriptionsServiceTransport() - adc.assert_called_once() - - -def test_subscriptions_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - SubscriptionsServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( - "https://www.googleapis.com/auth/chat.bot", - "https://www.googleapis.com/auth/chat.memberships", - "https://www.googleapis.com/auth/chat.memberships.readonly", - "https://www.googleapis.com/auth/chat.messages", - "https://www.googleapis.com/auth/chat.messages.reactions", - "https://www.googleapis.com/auth/chat.messages.reactions.readonly", - "https://www.googleapis.com/auth/chat.messages.readonly", - "https://www.googleapis.com/auth/chat.spaces", - "https://www.googleapis.com/auth/chat.spaces.readonly", - "https://www.googleapis.com/auth/meetings.space.created", - "https://www.googleapis.com/auth/meetings.space.readonly", - ), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.SubscriptionsServiceGrpcTransport, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - ], -) -def test_subscriptions_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=( - "https://www.googleapis.com/auth/chat.bot", - "https://www.googleapis.com/auth/chat.memberships", - "https://www.googleapis.com/auth/chat.memberships.readonly", - "https://www.googleapis.com/auth/chat.messages", - "https://www.googleapis.com/auth/chat.messages.reactions", - "https://www.googleapis.com/auth/chat.messages.reactions.readonly", - "https://www.googleapis.com/auth/chat.messages.readonly", - "https://www.googleapis.com/auth/chat.spaces", - "https://www.googleapis.com/auth/chat.spaces.readonly", - "https://www.googleapis.com/auth/meetings.space.created", - "https://www.googleapis.com/auth/meetings.space.readonly", - ), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.SubscriptionsServiceGrpcTransport, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - transports.SubscriptionsServiceRestTransport, - ], -) -def test_subscriptions_service_transport_auth_gdch_credentials(transport_class): - host = "https://language.com" - api_audience_tests = [None, "https://language2.com"] - api_audience_expect = [host, "https://language2.com"] - for t, e in zip(api_audience_tests, api_audience_expect): - with mock.patch.object(google.auth, "default", autospec=True) as adc: - gdch_mock = mock.MagicMock() - type(gdch_mock).with_gdch_audience = mock.PropertyMock( - return_value=gdch_mock - ) - adc.return_value = (gdch_mock, None) - transport_class(host=host, api_audience=t) - gdch_mock.with_gdch_audience.assert_called_once_with(e) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.SubscriptionsServiceGrpcTransport, grpc_helpers), - (transports.SubscriptionsServiceGrpcAsyncIOTransport, grpc_helpers_async), - ], -) -def test_subscriptions_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - - create_channel.assert_called_with( - "workspaceevents.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( - "https://www.googleapis.com/auth/chat.bot", - "https://www.googleapis.com/auth/chat.memberships", - "https://www.googleapis.com/auth/chat.memberships.readonly", - "https://www.googleapis.com/auth/chat.messages", - "https://www.googleapis.com/auth/chat.messages.reactions", - "https://www.googleapis.com/auth/chat.messages.reactions.readonly", - "https://www.googleapis.com/auth/chat.messages.readonly", - "https://www.googleapis.com/auth/chat.spaces", - "https://www.googleapis.com/auth/chat.spaces.readonly", - "https://www.googleapis.com/auth/meetings.space.created", - "https://www.googleapis.com/auth/meetings.space.readonly", - ), - scopes=["1", "2"], - default_host="workspaceevents.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.SubscriptionsServiceGrpcTransport, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - ], -) -def test_subscriptions_service_grpc_transport_client_cert_source_for_mtls( - transport_class, -): - cred = ga_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=None, - 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_subscriptions_service_http_transport_client_cert_source_for_mtls(): - cred = ga_credentials.AnonymousCredentials() - with mock.patch( - "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" - ) as mock_configure_mtls_channel: - transports.SubscriptionsServiceRestTransport( - credentials=cred, client_cert_source_for_mtls=client_cert_source_callback - ) - mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) - - -def test_subscriptions_service_rest_lro_client(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.AbstractOperationsClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "grpc_asyncio", - "rest", - ], -) -def test_subscriptions_service_host_no_port(transport_name): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="workspaceevents.googleapis.com" - ), - transport=transport_name, - ) - assert client.transport._host == ( - "workspaceevents.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://workspaceevents.googleapis.com" - ) - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "grpc_asyncio", - "rest", - ], -) -def test_subscriptions_service_host_with_port(transport_name): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="workspaceevents.googleapis.com:8000" - ), - transport=transport_name, - ) - assert client.transport._host == ( - "workspaceevents.googleapis.com:8000" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://workspaceevents.googleapis.com:8000" - ) - - -@pytest.mark.parametrize( - "transport_name", - [ - "rest", - ], -) -def test_subscriptions_service_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = SubscriptionsServiceClient( - credentials=creds1, - transport=transport_name, - ) - client2 = SubscriptionsServiceClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.create_subscription._session - session2 = client2.transport.create_subscription._session - assert session1 != session2 - session1 = client1.transport.delete_subscription._session - session2 = client2.transport.delete_subscription._session - assert session1 != session2 - session1 = client1.transport.get_subscription._session - session2 = client2.transport.get_subscription._session - assert session1 != session2 - session1 = client1.transport.list_subscriptions._session - session2 = client2.transport.list_subscriptions._session - assert session1 != session2 - session1 = client1.transport.update_subscription._session - session2 = client2.transport.update_subscription._session - assert session1 != session2 - session1 = client1.transport.reactivate_subscription._session - session2 = client2.transport.reactivate_subscription._session - assert session1 != session2 - - -def test_subscriptions_service_grpc_transport_channel(): - channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.SubscriptionsServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_subscriptions_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.SubscriptionsServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - 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", - [ - transports.SubscriptionsServiceGrpcTransport, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - ], -) -def test_subscriptions_service_transport_channel_mtls_with_client_cert_source( - transport_class, -): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel" - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - 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", - [ - transports.SubscriptionsServiceGrpcTransport, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - ], -) -def test_subscriptions_service_transport_channel_mtls_with_adc(transport_class): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object( - transport_class, "create_channel" - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_subscriptions_service_grpc_lro_client(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.OperationsClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - -def test_subscriptions_service_grpc_lro_async_client(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.OperationsAsyncClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - -def test_subscription_path(): - subscription = "squid" - expected = "subscriptions/{subscription}".format( - subscription=subscription, - ) - actual = SubscriptionsServiceClient.subscription_path(subscription) - assert expected == actual - - -def test_parse_subscription_path(): - expected = { - "subscription": "clam", - } - path = SubscriptionsServiceClient.subscription_path(**expected) - - # Check that the path construction is reversible. - actual = SubscriptionsServiceClient.parse_subscription_path(path) - assert expected == actual - - -def test_topic_path(): - project = "whelk" - topic = "octopus" - expected = "projects/{project}/topics/{topic}".format( - project=project, - topic=topic, - ) - actual = SubscriptionsServiceClient.topic_path(project, topic) - assert expected == actual - - -def test_parse_topic_path(): - expected = { - "project": "oyster", - "topic": "nudibranch", - } - path = SubscriptionsServiceClient.topic_path(**expected) - - # Check that the path construction is reversible. - actual = SubscriptionsServiceClient.parse_topic_path(path) - assert expected == actual - - -def test_user_path(): - user = "cuttlefish" - expected = "users/{user}".format( - user=user, - ) - actual = SubscriptionsServiceClient.user_path(user) - assert expected == actual - - -def test_parse_user_path(): - expected = { - "user": "mussel", - } - path = SubscriptionsServiceClient.user_path(**expected) - - # Check that the path construction is reversible. - actual = SubscriptionsServiceClient.parse_user_path(path) - assert expected == actual - - -def test_common_billing_account_path(): - billing_account = "winkle" - expected = "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - actual = SubscriptionsServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "nautilus", - } - path = SubscriptionsServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = SubscriptionsServiceClient.parse_common_billing_account_path(path) - assert expected == actual - - -def test_common_folder_path(): - folder = "scallop" - expected = "folders/{folder}".format( - folder=folder, - ) - actual = SubscriptionsServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "abalone", - } - path = SubscriptionsServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = SubscriptionsServiceClient.parse_common_folder_path(path) - assert expected == actual - - -def test_common_organization_path(): - organization = "squid" - expected = "organizations/{organization}".format( - organization=organization, - ) - actual = SubscriptionsServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "clam", - } - path = SubscriptionsServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = SubscriptionsServiceClient.parse_common_organization_path(path) - assert expected == actual - - -def test_common_project_path(): - project = "whelk" - expected = "projects/{project}".format( - project=project, - ) - actual = SubscriptionsServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "octopus", - } - path = SubscriptionsServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = SubscriptionsServiceClient.parse_common_project_path(path) - assert expected == actual - - -def test_common_location_path(): - project = "oyster" - location = "nudibranch" - expected = "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - actual = SubscriptionsServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "cuttlefish", - "location": "mussel", - } - path = SubscriptionsServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = SubscriptionsServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object( - transports.SubscriptionsServiceTransport, "_prep_wrapped_messages" - ) as prep: - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object( - transports.SubscriptionsServiceTransport, "_prep_wrapped_messages" - ) as prep: - transport_class = SubscriptionsServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -@pytest.mark.asyncio -async def test_transport_close_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" - ) as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_get_operation_rest_bad_request( - transport: str = "rest", request_type=operations_pb2.GetOperationRequest -): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - request = request_type() - request = json_format.ParseDict({"name": "operations/sample1"}, request) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_operation(request) - - -@pytest.mark.parametrize( - "request_type", - [ - operations_pb2.GetOperationRequest, - dict, - ], -) -def test_get_operation_rest(request_type): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request_init = {"name": "operations/sample1"} - request = request_type(**request_init) - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation() - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.get_operation(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, operations_pb2.Operation) - - -def test_get_operation(transport: str = "grpc"): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = operations_pb2.GetOperationRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_operation), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation() - response = client.get_operation(request) - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, operations_pb2.Operation) - - -@pytest.mark.asyncio -async def test_get_operation_async(transport: str = "grpc_asyncio"): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = operations_pb2.GetOperationRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_operation), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation() - ) - response = await client.get_operation(request) - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, operations_pb2.Operation) - - -def test_get_operation_field_headers(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = operations_pb2.GetOperationRequest() - request.name = "locations" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_operation), "__call__") as call: - call.return_value = operations_pb2.Operation() - - client.get_operation(request) - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=locations", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_get_operation_field_headers_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = operations_pb2.GetOperationRequest() - request.name = "locations" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_operation), "__call__") as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation() - ) - await client.get_operation(request) - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=locations", - ) in kw["metadata"] - - -def test_get_operation_from_dict(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_operation), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = operations_pb2.Operation() - - response = client.get_operation( - request={ - "name": "locations", - } - ) - call.assert_called() - - -@pytest.mark.asyncio -async def test_get_operation_from_dict_async(): - client = SubscriptionsServiceAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_operation), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - operations_pb2.Operation() - ) - response = await client.get_operation( - request={ - "name": "locations", - } - ) - call.assert_called() - - -def test_transport_close(): - transports = { - "rest": "_session", - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -def test_client_ctx(): - transports = [ - "rest", - "grpc", - ] - for transport in transports: - client = SubscriptionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - - -@pytest.mark.parametrize( - "client_class,transport_class", - [ - (SubscriptionsServiceClient, transports.SubscriptionsServiceGrpcTransport), - ( - SubscriptionsServiceAsyncClient, - transports.SubscriptionsServiceGrpcAsyncIOTransport, - ), - ], -) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) From 75571b2d61694744b7cfece51f1c0b83fbe01707 Mon Sep 17 00:00:00 2001 From: yoshi-code-bot <70984784+yoshi-code-bot@users.noreply.github.com> Date: Thu, 29 Feb 2024 15:29:54 -0800 Subject: [PATCH 09/13] chore: Update release-please config files (#12380) Update release-please config files --- release-please-config.json | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/release-please-config.json b/release-please-config.json index f880a3bf8ecd..afa3f6ef0358 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -80,21 +80,6 @@ ], "release-type": "python" }, - "packages/google-apps-events-subscriptions": { - "bump-minor-pre-major": true, - "bump-patch-for-minor-pre-major": true, - "component": "google-apps-events-subscriptions", - "extra-files": [ - "google/apps/events_subscriptions/gapic_version.py", - "google/apps/events_subscriptions_v1/gapic_version.py", - { - "jsonpath": "$.clientLibrary.version", - "path": "samples/generated_samples/snippet_metadata_google.apps.events.subscriptions.v1.json", - "type": "json" - } - ], - "release-type": "python" - }, "packages/google-apps-meet": { "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, From 4450f4ce787d11cfa11934dbd2acfe194474ca32 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 09:58:13 -0500 Subject: [PATCH 10/13] feat: [google-cloud-securitycenter] Added security center api V2 client library (#12361) - [ ] Regenerate this pull request now. PiperOrigin-RevId: 611571259 Source-Link: https://github.com/googleapis/googleapis/commit/e42dca2589c3f3e35d3ecd865d6264151dfb845f Source-Link: https://github.com/googleapis/googleapis-gen/commit/c7150bf535472a34b52d9836af97266402e49a08 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLXNlY3VyaXR5Y2VudGVyLy5Pd2xCb3QueWFtbCIsImgiOiJjNzE1MGJmNTM1NDcyYTM0YjUyZDk4MzZhZjk3MjY2NDAyZTQ5YTA4In0= BEGIN_COMMIT_OVERRIDE feat: Added security center api V2 client library fix(deps): Exclude google-auth 2.24.0 and 2.25.0 feat: Add container.create_time, vulnerability.offending_package, vulnerability.fixed_package, vulnerability.security_bulletin, vulnerability.cve.impact, vulnerability.cve.exploitation_activity, vulnerability.cve.observed_in_the_wild, vulnerability.cve.zero_day to finding's list of attributes END_COMMIT_OVERRIDE BEGIN_NESTED_COMMIT fix(deps): [google-cloud-securitycenter] Exclude google-auth 2.24.0 and 2.25.0 chore: Update gapic-generator-python to v1.14.4 PiperOrigin-RevId: 611561820 Source-Link: https://github.com/googleapis/googleapis/commit/87ef1fe57feede1f23b523f3c7fc4c3f2b92d6d2 Source-Link: https://github.com/googleapis/googleapis-gen/commit/197316137594aafad94dea31226528fbcc39310c Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLXNlY3VyaXR5Y2VudGVyLy5Pd2xCb3QueWFtbCIsImgiOiIxOTczMTYxMzc1OTRhYWZhZDk0ZGVhMzEyMjY1MjhmYmNjMzkzMTBjIn0= END_NESTED_COMMIT BEGIN_NESTED_COMMIT feat: [google-cloud-securitycenter] Add container.create_time, vulnerability.offending_package, vulnerability.fixed_package, vulnerability.security_bulletin, vulnerability.cve.impact, vulnerability.cve.exploitation_activity, vulnerability.cve.observed_in_the_wild, vulnerability.cve.zero_day to finding's list of attributes PiperOrigin-RevId: 611114785 Source-Link: https://github.com/googleapis/googleapis/commit/4bde6894aeeefdecfa2629515882c447df3c09ca Source-Link: https://github.com/googleapis/googleapis-gen/commit/b1cd799c4e1247f70471fc370963d14abfb0257c Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLXNlY3VyaXR5Y2VudGVyLy5Pd2xCb3QueWFtbCIsImgiOiJiMWNkNzk5YzRlMTI0N2Y3MDQ3MWZjMzcwOTYzZDE0YWJmYjAyNTdjIn0= END_NESTED_COMMIT BEGIN_NESTED_COMMIT feat: [google-cloud-securitycenter] Add load balancer, log entry, org policy, database.version, exfiltration.total_exfiltrated_bytes, file.disk_path, indicator.signature_type, and kubernetes.objects to finding's list of attributes PiperOrigin-RevId: 609614842 Source-Link: https://github.com/googleapis/googleapis/commit/d2c86cfe24eff21f328925cad726ed744a25bc57 Source-Link: https://github.com/googleapis/googleapis-gen/commit/612923bac4abea85e1d756124acef9912333d750 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLXNlY3VyaXR5Y2VudGVyLy5Pd2xCb3QueWFtbCIsImgiOiI2MTI5MjNiYWM0YWJlYTg1ZTFkNzU2MTI0YWNlZjk5MTIzMzNkNzUwIn0= END_NESTED_COMMIT --------- Co-authored-by: Owl Bot --- .../docs/index.rst | 8 + .../securitycenter_v2/security_center.rst | 10 + .../docs/securitycenter_v2/services_.rst | 6 + .../docs/securitycenter_v2/types_.rst | 6 + .../google/cloud/securitycenter/__init__.py | 11 + .../cloud/securitycenter/gapic_version.py | 2 +- .../cloud/securitycenter_v1/__init__.py | 18 +- .../cloud/securitycenter_v1/gapic_version.py | 2 +- .../services/security_center/async_client.py | 5 + .../services/security_center/client.py | 23 + .../cloud/securitycenter_v1/types/__init__.py | 18 +- .../securitycenter_v1/types/container.py | 8 + .../cloud/securitycenter_v1/types/database.py | 22 +- .../securitycenter_v1/types/exfiltration.py | 7 + .../cloud/securitycenter_v1/types/file.py | 30 + .../cloud/securitycenter_v1/types/finding.py | 26 +- .../securitycenter_v1/types/indicator.py | 23 + .../securitycenter_v1/types/kubernetes.py | 53 + .../securitycenter_v1/types/load_balancer.py | 46 + .../securitycenter_v1/types/log_entry.py | 94 + .../securitycenter_v1/types/mitre_attack.py | 220 +- .../securitycenter_v1/types/org_policy.py | 46 + .../cloud/securitycenter_v1/types/source.py | 4 +- .../securitycenter_v1/types/vulnerability.py | 189 +- .../securitycenter_v1beta1/gapic_version.py | 2 +- .../securitycenter_v1p1beta1/gapic_version.py | 2 +- .../cloud/securitycenter_v2/__init__.py | 224 + .../securitycenter_v2/gapic_metadata.json | 628 + .../cloud/securitycenter_v2/gapic_version.py | 16 + .../google/cloud/securitycenter_v2/py.typed | 2 + .../securitycenter_v2/services/__init__.py | 15 + .../services/security_center/__init__.py | 22 + .../services/security_center/async_client.py | 5667 +++ .../services/security_center/client.py | 6467 ++++ .../services/security_center/pagers.py | 1220 + .../security_center/transports/__init__.py | 36 + .../security_center/transports/base.py | 827 + .../security_center/transports/grpc.py | 1527 + .../transports/grpc_asyncio.py | 1547 + .../security_center/transports/rest.py | 6583 ++++ .../cloud/securitycenter_v2/types/__init__.py | 216 + .../cloud/securitycenter_v2/types/access.py | 194 + .../securitycenter_v2/types/application.py | 54 + .../types/attack_exposure.py | 112 + .../securitycenter_v2/types/attack_path.py | 228 + .../types/backup_disaster_recovery.py | 135 + .../types/bigquery_export.py | 139 + .../types/cloud_dlp_data_profile.py | 71 + .../types/cloud_dlp_inspection.py | 69 + .../securitycenter_v2/types/compliance.py | 60 + .../securitycenter_v2/types/connection.py | 97 + .../types/contact_details.py | 60 + .../securitycenter_v2/types/container.py | 79 + .../cloud/securitycenter_v2/types/database.py | 97 + .../securitycenter_v2/types/exfiltration.py | 95 + .../types/external_system.py | 190 + .../cloud/securitycenter_v2/types/file.py | 112 + .../cloud/securitycenter_v2/types/finding.py | 690 + .../securitycenter_v2/types/iam_binding.py | 77 + .../securitycenter_v2/types/indicator.py | 192 + .../securitycenter_v2/types/kernel_rootkit.py | 106 + .../securitycenter_v2/types/kubernetes.py | 398 + .../cloud/securitycenter_v2/types/label.py | 53 + .../securitycenter_v2/types/load_balancer.py | 46 + .../securitycenter_v2/types/log_entry.py | 93 + .../securitycenter_v2/types/mitre_attack.py | 322 + .../securitycenter_v2/types/mute_config.py | 143 + .../types/notification_config.py | 127 + .../types/notification_message.py | 69 + .../securitycenter_v2/types/org_policy.py | 46 + .../cloud/securitycenter_v2/types/process.py | 135 + .../cloud/securitycenter_v2/types/resource.py | 57 + .../types/resource_value_config.py | 178 + .../securitycenter_v2/types/security_marks.py | 94 + .../types/security_posture.py | 127 + .../types/securitycenter_service.py | 1838 + .../securitycenter_v2/types/simulation.py | 66 + .../cloud/securitycenter_v2/types/source.py | 87 + .../types/valued_resource.py | 128 + .../securitycenter_v2/types/vulnerability.py | 538 + ...tch_create_resource_value_configs_async.py | 57 + ...atch_create_resource_value_configs_sync.py | 57 + ...ecurity_center_bulk_mute_findings_async.py | 56 + ...security_center_bulk_mute_findings_sync.py | 56 + ...ty_center_create_big_query_export_async.py | 53 + ...ity_center_create_big_query_export_sync.py | 53 + ...ed_security_center_create_finding_async.py | 53 + ...ted_security_center_create_finding_sync.py | 53 + ...ecurity_center_create_mute_config_async.py | 58 + ...security_center_create_mute_config_sync.py | 58 + ...center_create_notification_config_async.py | 53 + ..._center_create_notification_config_sync.py | 53 + ...ted_security_center_create_source_async.py | 52 + ...ated_security_center_create_source_sync.py | 52 + ...ty_center_delete_big_query_export_async.py | 50 + ...ity_center_delete_big_query_export_sync.py | 50 + ...ecurity_center_delete_mute_config_async.py | 50 + ...security_center_delete_mute_config_sync.py | 50 + ...center_delete_notification_config_async.py | 50 + ..._center_delete_notification_config_sync.py | 50 + ...nter_delete_resource_value_config_async.py | 50 + ...enter_delete_resource_value_config_sync.py | 50 + ...urity_center_get_big_query_export_async.py | 52 + ...curity_center_get_big_query_export_sync.py | 52 + ...ed_security_center_get_iam_policy_async.py | 53 + ...ted_security_center_get_iam_policy_sync.py | 53 + ...d_security_center_get_mute_config_async.py | 52 + ...ed_security_center_get_mute_config_sync.py | 52 + ...ty_center_get_notification_config_async.py | 52 + ...ity_center_get_notification_config_sync.py | 52 + ..._center_get_resource_value_config_async.py | 52 + ...y_center_get_resource_value_config_sync.py | 52 + ...ed_security_center_get_simulation_async.py | 52 + ...ted_security_center_get_simulation_sync.py | 52 + ...erated_security_center_get_source_async.py | 52 + ...nerated_security_center_get_source_sync.py | 52 + ...curity_center_get_valued_resource_async.py | 52 + ...ecurity_center_get_valued_resource_sync.py | 52 + ...ed_security_center_group_findings_async.py | 54 + ...ted_security_center_group_findings_sync.py | 54 + ...security_center_list_attack_paths_async.py | 53 + ..._security_center_list_attack_paths_sync.py | 53 + ...ity_center_list_big_query_exports_async.py | 53 + ...rity_center_list_big_query_exports_sync.py | 53 + ...ted_security_center_list_findings_async.py | 53 + ...ated_security_center_list_findings_sync.py | 53 + ...security_center_list_mute_configs_async.py | 53 + ..._security_center_list_mute_configs_sync.py | 53 + ..._center_list_notification_configs_async.py | 53 + ...y_center_list_notification_configs_sync.py | 53 + ...enter_list_resource_value_configs_async.py | 53 + ...center_list_resource_value_configs_sync.py | 53 + ...ated_security_center_list_sources_async.py | 53 + ...rated_security_center_list_sources_sync.py | 53 + ...rity_center_list_valued_resources_async.py | 53 + ...urity_center_list_valued_resources_sync.py | 53 + ...security_center_set_finding_state_async.py | 53 + ..._security_center_set_finding_state_sync.py | 53 + ...ed_security_center_set_iam_policy_async.py | 53 + ...ted_security_center_set_iam_policy_sync.py | 53 + ...enerated_security_center_set_mute_async.py | 53 + ...generated_security_center_set_mute_sync.py | 53 + ...urity_center_test_iam_permissions_async.py | 54 + ...curity_center_test_iam_permissions_sync.py | 54 + ...ty_center_update_big_query_export_async.py | 51 + ...ity_center_update_big_query_export_sync.py | 51 + ...ity_center_update_external_system_async.py | 51 + ...rity_center_update_external_system_sync.py | 51 + ...ed_security_center_update_finding_async.py | 51 + ...ted_security_center_update_finding_sync.py | 51 + ...ecurity_center_update_mute_config_async.py | 56 + ...security_center_update_mute_config_sync.py | 56 + ...center_update_notification_config_async.py | 51 + ..._center_update_notification_config_sync.py | 51 + ...nter_update_resource_value_config_async.py | 55 + ...enter_update_resource_value_config_sync.py | 55 + ...rity_center_update_security_marks_async.py | 51 + ...urity_center_update_security_marks_sync.py | 51 + ...ted_security_center_update_source_async.py | 51 + ...ated_security_center_update_source_sync.py | 51 + ...tadata_google.cloud.securitycenter.v1.json | 2 +- ...a_google.cloud.securitycenter.v1beta1.json | 2 +- ...google.cloud.securitycenter.v1p1beta1.json | 2 +- ...tadata_google.cloud.securitycenter.v2.json | 6607 ++++ .../fixup_securitycenter_v2_keywords.py | 215 + packages/google-cloud-securitycenter/setup.py | 4 +- .../securitycenter_v1/test_security_center.py | 192 +- .../unit/gapic/securitycenter_v2/__init__.py | 15 + .../securitycenter_v2/test_security_center.py | 29017 ++++++++++++++++ 169 files changed, 73415 insertions(+), 135 deletions(-) create mode 100644 packages/google-cloud-securitycenter/docs/securitycenter_v2/security_center.rst create mode 100644 packages/google-cloud-securitycenter/docs/securitycenter_v2/services_.rst create mode 100644 packages/google-cloud-securitycenter/docs/securitycenter_v2/types_.rst create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/load_balancer.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/log_entry.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/org_policy.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/__init__.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/gapic_metadata.json create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/gapic_version.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/py.typed create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/__init__.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/__init__.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/async_client.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/client.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/pagers.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/__init__.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/base.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/grpc.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/grpc_asyncio.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/rest.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/__init__.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/access.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/application.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/attack_exposure.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/attack_path.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/backup_disaster_recovery.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/bigquery_export.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/cloud_dlp_data_profile.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/cloud_dlp_inspection.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/compliance.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/connection.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/contact_details.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/container.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/database.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/exfiltration.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/external_system.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/file.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/finding.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/iam_binding.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/indicator.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/kernel_rootkit.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/kubernetes.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/label.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/load_balancer.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/log_entry.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/mitre_attack.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/mute_config.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/notification_config.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/notification_message.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/org_policy.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/process.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/resource.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/resource_value_config.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/security_marks.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/security_posture.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/securitycenter_service.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/simulation.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/source.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/valued_resource.py create mode 100644 packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/vulnerability.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_batch_create_resource_value_configs_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_batch_create_resource_value_configs_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_bulk_mute_findings_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_bulk_mute_findings_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_big_query_export_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_big_query_export_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_finding_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_finding_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_mute_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_mute_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_notification_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_notification_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_source_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_source_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_big_query_export_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_big_query_export_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_mute_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_mute_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_notification_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_notification_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_resource_value_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_resource_value_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_big_query_export_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_big_query_export_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_iam_policy_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_iam_policy_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_mute_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_mute_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_notification_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_notification_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_resource_value_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_resource_value_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_simulation_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_simulation_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_source_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_source_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_valued_resource_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_valued_resource_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_group_findings_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_group_findings_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_attack_paths_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_attack_paths_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_big_query_exports_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_big_query_exports_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_findings_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_findings_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_mute_configs_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_mute_configs_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_notification_configs_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_notification_configs_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_resource_value_configs_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_resource_value_configs_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_sources_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_sources_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_valued_resources_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_valued_resources_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_finding_state_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_finding_state_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_iam_policy_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_iam_policy_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_mute_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_mute_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_test_iam_permissions_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_test_iam_permissions_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_big_query_export_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_big_query_export_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_external_system_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_external_system_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_finding_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_finding_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_mute_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_mute_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_notification_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_notification_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_resource_value_config_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_resource_value_config_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_security_marks_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_security_marks_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_source_async.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_source_sync.py create mode 100644 packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v2.json create mode 100644 packages/google-cloud-securitycenter/scripts/fixup_securitycenter_v2_keywords.py create mode 100644 packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v2/__init__.py create mode 100644 packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v2/test_security_center.py diff --git a/packages/google-cloud-securitycenter/docs/index.rst b/packages/google-cloud-securitycenter/docs/index.rst index 3d7c999e8772..34ebeb002c30 100644 --- a/packages/google-cloud-securitycenter/docs/index.rst +++ b/packages/google-cloud-securitycenter/docs/index.rst @@ -30,6 +30,14 @@ API Reference securitycenter_v1p1beta1/services_ securitycenter_v1p1beta1/types_ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + securitycenter_v2/services_ + securitycenter_v2/types_ + Changelog --------- diff --git a/packages/google-cloud-securitycenter/docs/securitycenter_v2/security_center.rst b/packages/google-cloud-securitycenter/docs/securitycenter_v2/security_center.rst new file mode 100644 index 000000000000..6b9d3b9b1795 --- /dev/null +++ b/packages/google-cloud-securitycenter/docs/securitycenter_v2/security_center.rst @@ -0,0 +1,10 @@ +SecurityCenter +-------------------------------- + +.. automodule:: google.cloud.securitycenter_v2.services.security_center + :members: + :inherited-members: + +.. automodule:: google.cloud.securitycenter_v2.services.security_center.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-securitycenter/docs/securitycenter_v2/services_.rst b/packages/google-cloud-securitycenter/docs/securitycenter_v2/services_.rst new file mode 100644 index 000000000000..adb8a6096090 --- /dev/null +++ b/packages/google-cloud-securitycenter/docs/securitycenter_v2/services_.rst @@ -0,0 +1,6 @@ +Services for Google Cloud Securitycenter v2 API +=============================================== +.. toctree:: + :maxdepth: 2 + + security_center diff --git a/packages/google-cloud-securitycenter/docs/securitycenter_v2/types_.rst b/packages/google-cloud-securitycenter/docs/securitycenter_v2/types_.rst new file mode 100644 index 000000000000..3210d372fb24 --- /dev/null +++ b/packages/google-cloud-securitycenter/docs/securitycenter_v2/types_.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Securitycenter v2 API +============================================ + +.. automodule:: google.cloud.securitycenter_v2.types + :members: + :show-inheritance: diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter/__init__.py index 046271412037..9444e7513937 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter/__init__.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter/__init__.py @@ -60,12 +60,15 @@ from google.cloud.securitycenter_v1.types.kernel_rootkit import KernelRootkit from google.cloud.securitycenter_v1.types.kubernetes import Kubernetes from google.cloud.securitycenter_v1.types.label import Label +from google.cloud.securitycenter_v1.types.load_balancer import LoadBalancer +from google.cloud.securitycenter_v1.types.log_entry import CloudLoggingEntry, LogEntry from google.cloud.securitycenter_v1.types.mitre_attack import MitreAttack from google.cloud.securitycenter_v1.types.mute_config import MuteConfig from google.cloud.securitycenter_v1.types.notification_config import NotificationConfig from google.cloud.securitycenter_v1.types.notification_message import ( NotificationMessage, ) +from google.cloud.securitycenter_v1.types.org_policy import OrgPolicy from google.cloud.securitycenter_v1.types.organization_settings import ( OrganizationSettings, ) @@ -143,7 +146,9 @@ from google.cloud.securitycenter_v1.types.vulnerability import ( Cve, Cvssv3, + Package, Reference, + SecurityBulletin, Vulnerability, ) @@ -177,10 +182,14 @@ "KernelRootkit", "Kubernetes", "Label", + "LoadBalancer", + "CloudLoggingEntry", + "LogEntry", "MitreAttack", "MuteConfig", "NotificationConfig", "NotificationMessage", + "OrgPolicy", "OrganizationSettings", "EnvironmentVariable", "Process", @@ -248,6 +257,8 @@ "Source", "Cve", "Cvssv3", + "Package", "Reference", + "SecurityBulletin", "Vulnerability", ) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter/gapic_version.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter/gapic_version.py index 484507c567a0..360a0d13ebdd 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter/gapic_version.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.27.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/__init__.py index eb619350b025..b9cc2f203140 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/__init__.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/__init__.py @@ -44,10 +44,13 @@ from .types.kernel_rootkit import KernelRootkit from .types.kubernetes import Kubernetes from .types.label import Label +from .types.load_balancer import LoadBalancer +from .types.log_entry import CloudLoggingEntry, LogEntry from .types.mitre_attack import MitreAttack from .types.mute_config import MuteConfig from .types.notification_config import NotificationConfig from .types.notification_message import NotificationMessage +from .types.org_policy import OrgPolicy from .types.organization_settings import OrganizationSettings from .types.process import EnvironmentVariable, Process from .types.resource import Resource @@ -116,7 +119,14 @@ UpdateSourceRequest, ) from .types.source import Source -from .types.vulnerability import Cve, Cvssv3, Reference, Vulnerability +from .types.vulnerability import ( + Cve, + Cvssv3, + Package, + Reference, + SecurityBulletin, + Vulnerability, +) __all__ = ( "SecurityCenterAsyncClient", @@ -129,6 +139,7 @@ "BulkMuteFindingsResponse", "CloudDlpDataProfile", "CloudDlpInspection", + "CloudLoggingEntry", "Compliance", "Connection", "Contact", @@ -192,16 +203,21 @@ "ListSecurityHealthAnalyticsCustomModulesResponse", "ListSourcesRequest", "ListSourcesResponse", + "LoadBalancer", + "LogEntry", "MitreAttack", "MuteConfig", "NotificationConfig", "NotificationMessage", + "OrgPolicy", "OrganizationSettings", + "Package", "Process", "Reference", "Resource", "RunAssetDiscoveryRequest", "RunAssetDiscoveryResponse", + "SecurityBulletin", "SecurityCenterClient", "SecurityHealthAnalyticsCustomModule", "SecurityMarks", diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/gapic_version.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/gapic_version.py index 484507c567a0..360a0d13ebdd 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/gapic_version.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.27.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/services/security_center/async_client.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/services/security_center/async_client.py index a5e58e188f46..b70a5aba8b75 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/services/security_center/async_client.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/services/security_center/async_client.py @@ -77,6 +77,8 @@ indicator, kernel_rootkit, kubernetes, + load_balancer, + log_entry, mitre_attack, ) from google.cloud.securitycenter_v1.types import external_system as gcs_external_system @@ -97,6 +99,7 @@ from google.cloud.securitycenter_v1.types import mute_config from google.cloud.securitycenter_v1.types import mute_config as gcs_mute_config from google.cloud.securitycenter_v1.types import notification_config +from google.cloud.securitycenter_v1.types import org_policy from google.cloud.securitycenter_v1.types import organization_settings from google.cloud.securitycenter_v1.types import security_marks from google.cloud.securitycenter_v1.types import securitycenter_service @@ -155,6 +158,8 @@ class SecurityCenterAsyncClient: parse_organization_settings_path = staticmethod( SecurityCenterClient.parse_organization_settings_path ) + policy_path = staticmethod(SecurityCenterClient.policy_path) + parse_policy_path = staticmethod(SecurityCenterClient.parse_policy_path) security_health_analytics_custom_module_path = staticmethod( SecurityCenterClient.security_health_analytics_custom_module_path ) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/services/security_center/client.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/services/security_center/client.py index 0c7a98d8a626..04459fd18a8e 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/services/security_center/client.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/services/security_center/client.py @@ -81,6 +81,8 @@ indicator, kernel_rootkit, kubernetes, + load_balancer, + log_entry, mitre_attack, ) from google.cloud.securitycenter_v1.types import external_system as gcs_external_system @@ -101,6 +103,7 @@ from google.cloud.securitycenter_v1.types import mute_config from google.cloud.securitycenter_v1.types import mute_config as gcs_mute_config from google.cloud.securitycenter_v1.types import notification_config +from google.cloud.securitycenter_v1.types import org_policy from google.cloud.securitycenter_v1.types import organization_settings from google.cloud.securitycenter_v1.types import security_marks from google.cloud.securitycenter_v1.types import securitycenter_service @@ -423,6 +426,26 @@ def parse_organization_settings_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def policy_path( + organization: str, + constraint_name: str, + ) -> str: + """Returns a fully-qualified policy string.""" + return "organizations/{organization}/policies/{constraint_name}".format( + organization=organization, + constraint_name=constraint_name, + ) + + @staticmethod + def parse_policy_path(path: str) -> Dict[str, str]: + """Parses a policy path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/policies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def security_health_analytics_custom_module_path( organization: str, diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/__init__.py index 8da5695c7bbd..f25774026695 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/__init__.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/__init__.py @@ -38,10 +38,13 @@ from .kernel_rootkit import KernelRootkit from .kubernetes import Kubernetes from .label import Label +from .load_balancer import LoadBalancer +from .log_entry import CloudLoggingEntry, LogEntry from .mitre_attack import MitreAttack from .mute_config import MuteConfig from .notification_config import NotificationConfig from .notification_message import NotificationMessage +from .org_policy import OrgPolicy from .organization_settings import OrganizationSettings from .process import EnvironmentVariable, Process from .resource import Resource @@ -108,7 +111,14 @@ UpdateSourceRequest, ) from .source import Source -from .vulnerability import Cve, Cvssv3, Reference, Vulnerability +from .vulnerability import ( + Cve, + Cvssv3, + Package, + Reference, + SecurityBulletin, + Vulnerability, +) __all__ = ( "Access", @@ -138,10 +148,14 @@ "KernelRootkit", "Kubernetes", "Label", + "LoadBalancer", + "CloudLoggingEntry", + "LogEntry", "MitreAttack", "MuteConfig", "NotificationConfig", "NotificationMessage", + "OrgPolicy", "OrganizationSettings", "EnvironmentVariable", "Process", @@ -209,6 +223,8 @@ "Source", "Cve", "Cvssv3", + "Package", "Reference", + "SecurityBulletin", "Vulnerability", ) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/container.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/container.py index 1a005bb78739..f76c885b3c38 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/container.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/container.py @@ -17,6 +17,7 @@ from typing import MutableMapping, MutableSequence +from google.protobuf import timestamp_pb2 # type: ignore import proto # type: ignore from google.cloud.securitycenter_v1.types import label @@ -47,6 +48,8 @@ class Container(proto.Message): labels (MutableSequence[google.cloud.securitycenter_v1.types.Label]): Container labels, as provided by the container runtime. + create_time (google.protobuf.timestamp_pb2.Timestamp): + The time that the container was created. """ name: str = proto.Field( @@ -66,6 +69,11 @@ class Container(proto.Message): number=4, message=label.Label, ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/database.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/database.py index 5eb7c3f3011c..2a1ed6e5cdd7 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/database.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/database.py @@ -35,16 +35,16 @@ class Database(proto.Message): name `__ populated because these resource types, such as Cloud SQL databases, are not yet supported by Cloud Asset Inventory. In these cases only the - display name is provided. Some database resources may not have the - `full resource - name `__ populated - because these resource types are not yet supported by Cloud Asset - Inventory (e.g. Cloud SQL databases). In these cases only the - display name will be provided. + display name is provided. Attributes: name (str): - The `full resource + Some database resources may not have the `full resource + name `__ + populated because these resource types are not yet supported + by Cloud Asset Inventory (e.g. Cloud SQL databases). In + these cases only the display name will be provided. The + `full resource name `__ of the database that the user connected to, if it is supported by Cloud Asset Inventory. @@ -62,6 +62,10 @@ class Database(proto.Message): The target usernames, roles, or groups of an SQL privilege grant, which is not an IAM policy change. + version (str): + The version of the database, for example, POSTGRES_14. See + `the complete + list `__. """ name: str = proto.Field( @@ -84,6 +88,10 @@ class Database(proto.Message): proto.STRING, number=5, ) + version: str = proto.Field( + proto.STRING, + number=6, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/exfiltration.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/exfiltration.py index 8ec6b1787f26..3147dae302a9 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/exfiltration.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/exfiltration.py @@ -44,6 +44,9 @@ class Exfiltration(proto.Message): If there are multiple targets, each target would get a complete copy of the "joined" source data. + total_exfiltrated_bytes (int): + Total exfiltrated bytes processed for the + entire job. """ sources: MutableSequence["ExfilResource"] = proto.RepeatedField( @@ -56,6 +59,10 @@ class Exfiltration(proto.Message): number=2, message="ExfilResource", ) + total_exfiltrated_bytes: int = proto.Field( + proto.INT64, + number=3, + ) class ExfilResource(proto.Message): diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/file.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/file.py index aeea18dc7b8b..a44d5508acf5 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/file.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/file.py @@ -51,8 +51,33 @@ class File(proto.Message): contents (str): Prefix of the file contents as a JSON-encoded string. + disk_path (google.cloud.securitycenter_v1.types.File.DiskPath): + Path of the file in terms of underlying + disk/partition identifiers. """ + class DiskPath(proto.Message): + r"""Path of the file in terms of underlying disk/partition + identifiers. + + Attributes: + partition_uuid (str): + UUID of the partition (format + https://wiki.archlinux.org/title/persistent_block_device_naming#by-uuid) + relative_path (str): + Relative path of the file in the partition as a JSON encoded + string. Example: /home/user1/executable_file.sh + """ + + partition_uuid: str = proto.Field( + proto.STRING, + number=1, + ) + relative_path: str = proto.Field( + proto.STRING, + number=2, + ) + path: str = proto.Field( proto.STRING, number=1, @@ -77,6 +102,11 @@ class File(proto.Message): proto.STRING, number=6, ) + disk_path: DiskPath = proto.Field( + proto.MESSAGE, + number=7, + message=DiskPath, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/finding.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/finding.py index 5bec59aa5011..e78da17c161c 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/finding.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/finding.py @@ -47,7 +47,8 @@ from google.cloud.securitycenter_v1.types import database as gcs_database from google.cloud.securitycenter_v1.types import indicator as gcs_indicator from google.cloud.securitycenter_v1.types import kubernetes as gcs_kubernetes -from google.cloud.securitycenter_v1.types import process +from google.cloud.securitycenter_v1.types import load_balancer, log_entry +from google.cloud.securitycenter_v1.types import org_policy, process __protobuf__ = proto.module( package="google.cloud.securitycenter.v1", @@ -242,11 +243,19 @@ class Finding(proto.Message): with the finding. kernel_rootkit (google.cloud.securitycenter_v1.types.KernelRootkit): Signature of the kernel rootkit. + org_policies (MutableSequence[google.cloud.securitycenter_v1.types.OrgPolicy]): + Contains information about the org policies + associated with the finding. application (google.cloud.securitycenter_v1.types.Application): Represents an application associated with the finding. backup_disaster_recovery (google.cloud.securitycenter_v1.types.BackupDisasterRecovery): Fields related to Backup and DR findings. + log_entries (MutableSequence[google.cloud.securitycenter_v1.types.LogEntry]): + Log entries that are relevant to the finding. + load_balancers (MutableSequence[google.cloud.securitycenter_v1.types.LoadBalancer]): + The load balancers associated with the + finding. """ class State(proto.Enum): @@ -589,6 +598,11 @@ class FindingClass(proto.Enum): number=50, message=gcs_kernel_rootkit.KernelRootkit, ) + org_policies: MutableSequence[org_policy.OrgPolicy] = proto.RepeatedField( + proto.MESSAGE, + number=51, + message=org_policy.OrgPolicy, + ) application: gcs_application.Application = proto.Field( proto.MESSAGE, number=53, @@ -601,6 +615,16 @@ class FindingClass(proto.Enum): message=gcs_backup_disaster_recovery.BackupDisasterRecovery, ) ) + log_entries: MutableSequence[log_entry.LogEntry] = proto.RepeatedField( + proto.MESSAGE, + number=57, + message=log_entry.LogEntry, + ) + load_balancers: MutableSequence[load_balancer.LoadBalancer] = proto.RepeatedField( + proto.MESSAGE, + number=58, + message=load_balancer.LoadBalancer, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/indicator.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/indicator.py index 46f5254b8db5..4aa358a985bf 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/indicator.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/indicator.py @@ -70,8 +70,26 @@ class ProcessSignature(proto.Message): matched. This field is a member of `oneof`_ ``signature``. + signature_type (google.cloud.securitycenter_v1.types.Indicator.ProcessSignature.SignatureType): + Describes the type of resource associated + with the signature. """ + class SignatureType(proto.Enum): + r"""Possible resource types to be associated with a signature. + + Values: + SIGNATURE_TYPE_UNSPECIFIED (0): + The default signature type. + SIGNATURE_TYPE_PROCESS (1): + Used for signatures concerning processes. + SIGNATURE_TYPE_FILE (2): + Used for signatures concerning disks. + """ + SIGNATURE_TYPE_UNSPECIFIED = 0 + SIGNATURE_TYPE_PROCESS = 1 + SIGNATURE_TYPE_FILE = 2 + class MemoryHashSignature(proto.Message): r"""A signature corresponding to memory page hashes. @@ -146,6 +164,11 @@ class YaraRuleSignature(proto.Message): message="Indicator.ProcessSignature.YaraRuleSignature", ) ) + signature_type: "Indicator.ProcessSignature.SignatureType" = proto.Field( + proto.ENUM, + number=8, + enum="Indicator.ProcessSignature.SignatureType", + ) ip_addresses: MutableSequence[str] = proto.RepeatedField( proto.STRING, diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/kubernetes.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/kubernetes.py index fc4436f4b083..f482daa0f639 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/kubernetes.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/kubernetes.py @@ -59,6 +59,8 @@ class Kubernetes(proto.Message): Provides information on any Kubernetes access reviews (privilege checks) relevant to the finding. + objects (MutableSequence[google.cloud.securitycenter_v1.types.Kubernetes.Object]): + Kubernetes objects related to the finding. """ class Pod(proto.Message): @@ -310,6 +312,52 @@ class AccessReview(proto.Message): number=7, ) + class Object(proto.Message): + r"""Kubernetes object related to the finding, uniquely identified + by GKNN. Used if the object Kind is not one of Pod, Node, + NodePool, Binding, or AccessReview. + + Attributes: + group (str): + Kubernetes object group, such as + "policy.k8s.io/v1". + kind (str): + Kubernetes object kind, such as "Namespace". + ns (str): + Kubernetes object namespace. Must be a valid + DNS label. Named "ns" to avoid collision with + C++ namespace keyword. For details see + https://kubernetes.io/docs/tasks/administer-cluster/namespaces/. + name (str): + Kubernetes object name. For details see + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/. + containers (MutableSequence[google.cloud.securitycenter_v1.types.Container]): + Pod containers associated with this finding, + if any. + """ + + group: str = proto.Field( + proto.STRING, + number=1, + ) + kind: str = proto.Field( + proto.STRING, + number=2, + ) + ns: str = proto.Field( + proto.STRING, + number=3, + ) + name: str = proto.Field( + proto.STRING, + number=4, + ) + containers: MutableSequence[container.Container] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=container.Container, + ) + pods: MutableSequence[Pod] = proto.RepeatedField( proto.MESSAGE, number=1, @@ -340,6 +388,11 @@ class AccessReview(proto.Message): number=6, message=AccessReview, ) + objects: MutableSequence[Object] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message=Object, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/load_balancer.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/load_balancer.py new file mode 100644 index 000000000000..ef34b965e550 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/load_balancer.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v1", + manifest={ + "LoadBalancer", + }, +) + + +class LoadBalancer(proto.Message): + r"""Contains information related to the load balancer associated + with the finding. + + Attributes: + name (str): + The name of the load balancer associated with + the finding. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/log_entry.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/log_entry.py new file mode 100644 index 000000000000..8157df9dc4b9 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/log_entry.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v1", + manifest={ + "LogEntry", + "CloudLoggingEntry", + }, +) + + +class LogEntry(proto.Message): + r"""An individual entry in a log. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + cloud_logging_entry (google.cloud.securitycenter_v1.types.CloudLoggingEntry): + An individual entry in a log stored in Cloud + Logging. + + This field is a member of `oneof`_ ``log_entry``. + """ + + cloud_logging_entry: "CloudLoggingEntry" = proto.Field( + proto.MESSAGE, + number=1, + oneof="log_entry", + message="CloudLoggingEntry", + ) + + +class CloudLoggingEntry(proto.Message): + r"""Metadata taken from a `Cloud Logging + LogEntry `__ + + Attributes: + insert_id (str): + A unique identifier for the log entry. + log_id (str): + The type of the log (part of ``log_name``. ``log_name`` is + the resource name of the log to which this log entry + belongs). For example: + ``cloudresourcemanager.googleapis.com/activity``. Note that + this field is not URL-encoded, unlike the ``LOG_ID`` field + in ``LogEntry``. + resource_container (str): + The organization, folder, or project of the + monitored resource that produced this log entry. + timestamp (google.protobuf.timestamp_pb2.Timestamp): + The time the event described by the log entry + occurred. + """ + + insert_id: str = proto.Field( + proto.STRING, + number=1, + ) + log_id: str = proto.Field( + proto.STRING, + number=2, + ) + resource_container: str = proto.Field( + proto.STRING, + number=3, + ) + timestamp: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/mitre_attack.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/mitre_attack.py index 75d28ce0faa2..6b340c329b7f 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/mitre_attack.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/mitre_attack.py @@ -111,117 +111,187 @@ class Tactic(proto.Enum): class Technique(proto.Enum): r"""MITRE ATT&CK techniques that can be referenced by SCC findings. See: https://attack.mitre.org/techniques/enterprise/ + Next ID: 59 Values: TECHNIQUE_UNSPECIFIED (0): Unspecified value. - ACTIVE_SCANNING (1): - T1595 - SCANNING_IP_BLOCKS (2): - T1595.001 - INGRESS_TOOL_TRANSFER (3): - T1105 - NATIVE_API (4): - T1106 - SHARED_MODULES (5): - T1129 + MASQUERADING (49): + T1036 + MATCH_LEGITIMATE_NAME_OR_LOCATION (50): + T1036.005 + BOOT_OR_LOGON_INITIALIZATION_SCRIPTS (37): + T1037 + STARTUP_ITEMS (38): + T1037.005 + NETWORK_SERVICE_DISCOVERY (32): + T1046 + PROCESS_DISCOVERY (56): + T1057 COMMAND_AND_SCRIPTING_INTERPRETER (6): T1059 UNIX_SHELL (7): T1059.004 - RESOURCE_HIJACKING (8): - T1496 - PROXY (9): - T1090 - EXTERNAL_PROXY (10): - T1090.002 - MULTI_HOP_PROXY (11): - T1090.003 - DYNAMIC_RESOLUTION (12): - T1568 - UNSECURED_CREDENTIALS (13): - T1552 + PERMISSION_GROUPS_DISCOVERY (18): + T1069 + CLOUD_GROUPS (19): + T1069.003 + APPLICATION_LAYER_PROTOCOL (45): + T1071 + DNS (46): + T1071.004 + SOFTWARE_DEPLOYMENT_TOOLS (47): + T1072 VALID_ACCOUNTS (14): T1078 + DEFAULT_ACCOUNTS (35): + T1078.001 LOCAL_ACCOUNTS (15): T1078.003 CLOUD_ACCOUNTS (16): T1078.004 - NETWORK_DENIAL_OF_SERVICE (17): - T1498 - PERMISSION_GROUPS_DISCOVERY (18): - T1069 - CLOUD_GROUPS (19): - T1069.003 - EXFILTRATION_OVER_WEB_SERVICE (20): - T1567 - EXFILTRATION_TO_CLOUD_STORAGE (21): - T1567.002 + PROXY (9): + T1090 + EXTERNAL_PROXY (10): + T1090.002 + MULTI_HOP_PROXY (11): + T1090.003 ACCOUNT_MANIPULATION (22): T1098 + ADDITIONAL_CLOUD_CREDENTIALS (40): + T1098.001 SSH_AUTHORIZED_KEYS (23): T1098.004 - CREATE_OR_MODIFY_SYSTEM_PROCESS (24): - T1543 - STEAL_WEB_SESSION_COOKIE (25): - T1539 - MODIFY_CLOUD_COMPUTE_INFRASTRUCTURE (26): - T1578 + ADDITIONAL_CONTAINER_CLUSTER_ROLES (58): + T1098.006 + INGRESS_TOOL_TRANSFER (3): + T1105 + NATIVE_API (4): + T1106 + BRUTE_FORCE (44): + T1110 + SHARED_MODULES (5): + T1129 + ACCESS_TOKEN_MANIPULATION (33): + T1134 + TOKEN_IMPERSONATION_OR_THEFT (39): + T1134.001 EXPLOIT_PUBLIC_FACING_APPLICATION (27): T1190 - MODIFY_AUTHENTICATION_PROCESS (28): - T1556 - DATA_DESTRUCTION (29): - T1485 DOMAIN_POLICY_MODIFICATION (30): T1484 - IMPAIR_DEFENSES (31): - T1562 - NETWORK_SERVICE_DISCOVERY (32): - T1046 - ACCESS_TOKEN_MANIPULATION (33): - T1134 + DATA_DESTRUCTION (29): + T1485 + SERVICE_STOP (52): + T1489 + INHIBIT_SYSTEM_RECOVERY (36): + T1490 + RESOURCE_HIJACKING (8): + T1496 + NETWORK_DENIAL_OF_SERVICE (17): + T1498 + CLOUD_SERVICE_DISCOVERY (48): + T1526 + STEAL_APPLICATION_ACCESS_TOKEN (42): + T1528 + ACCOUNT_ACCESS_REMOVAL (51): + T1531 + STEAL_WEB_SESSION_COOKIE (25): + T1539 + CREATE_OR_MODIFY_SYSTEM_PROCESS (24): + T1543 ABUSE_ELEVATION_CONTROL_MECHANISM (34): T1548 - DEFAULT_ACCOUNTS (35): - T1078.001 + UNSECURED_CREDENTIALS (13): + T1552 + MODIFY_AUTHENTICATION_PROCESS (28): + T1556 + IMPAIR_DEFENSES (31): + T1562 + DISABLE_OR_MODIFY_TOOLS (55): + T1562.001 + EXFILTRATION_OVER_WEB_SERVICE (20): + T1567 + EXFILTRATION_TO_CLOUD_STORAGE (21): + T1567.002 + DYNAMIC_RESOLUTION (12): + T1568 + LATERAL_TOOL_TRANSFER (41): + T1570 + MODIFY_CLOUD_COMPUTE_INFRASTRUCTURE (26): + T1578 + CREATE_SNAPSHOT (54): + T1578.001 + CLOUD_INFRASTRUCTURE_DISCOVERY (53): + T1580 + OBTAIN_CAPABILITIES (43): + T1588 + ACTIVE_SCANNING (1): + T1595 + SCANNING_IP_BLOCKS (2): + T1595.001 + CONTAINER_AND_RESOURCE_DISCOVERY (57): + T1613 """ TECHNIQUE_UNSPECIFIED = 0 - ACTIVE_SCANNING = 1 - SCANNING_IP_BLOCKS = 2 - INGRESS_TOOL_TRANSFER = 3 - NATIVE_API = 4 - SHARED_MODULES = 5 + MASQUERADING = 49 + MATCH_LEGITIMATE_NAME_OR_LOCATION = 50 + BOOT_OR_LOGON_INITIALIZATION_SCRIPTS = 37 + STARTUP_ITEMS = 38 + NETWORK_SERVICE_DISCOVERY = 32 + PROCESS_DISCOVERY = 56 COMMAND_AND_SCRIPTING_INTERPRETER = 6 UNIX_SHELL = 7 - RESOURCE_HIJACKING = 8 - PROXY = 9 - EXTERNAL_PROXY = 10 - MULTI_HOP_PROXY = 11 - DYNAMIC_RESOLUTION = 12 - UNSECURED_CREDENTIALS = 13 + PERMISSION_GROUPS_DISCOVERY = 18 + CLOUD_GROUPS = 19 + APPLICATION_LAYER_PROTOCOL = 45 + DNS = 46 + SOFTWARE_DEPLOYMENT_TOOLS = 47 VALID_ACCOUNTS = 14 + DEFAULT_ACCOUNTS = 35 LOCAL_ACCOUNTS = 15 CLOUD_ACCOUNTS = 16 - NETWORK_DENIAL_OF_SERVICE = 17 - PERMISSION_GROUPS_DISCOVERY = 18 - CLOUD_GROUPS = 19 - EXFILTRATION_OVER_WEB_SERVICE = 20 - EXFILTRATION_TO_CLOUD_STORAGE = 21 + PROXY = 9 + EXTERNAL_PROXY = 10 + MULTI_HOP_PROXY = 11 ACCOUNT_MANIPULATION = 22 + ADDITIONAL_CLOUD_CREDENTIALS = 40 SSH_AUTHORIZED_KEYS = 23 - CREATE_OR_MODIFY_SYSTEM_PROCESS = 24 - STEAL_WEB_SESSION_COOKIE = 25 - MODIFY_CLOUD_COMPUTE_INFRASTRUCTURE = 26 + ADDITIONAL_CONTAINER_CLUSTER_ROLES = 58 + INGRESS_TOOL_TRANSFER = 3 + NATIVE_API = 4 + BRUTE_FORCE = 44 + SHARED_MODULES = 5 + ACCESS_TOKEN_MANIPULATION = 33 + TOKEN_IMPERSONATION_OR_THEFT = 39 EXPLOIT_PUBLIC_FACING_APPLICATION = 27 - MODIFY_AUTHENTICATION_PROCESS = 28 - DATA_DESTRUCTION = 29 DOMAIN_POLICY_MODIFICATION = 30 - IMPAIR_DEFENSES = 31 - NETWORK_SERVICE_DISCOVERY = 32 - ACCESS_TOKEN_MANIPULATION = 33 + DATA_DESTRUCTION = 29 + SERVICE_STOP = 52 + INHIBIT_SYSTEM_RECOVERY = 36 + RESOURCE_HIJACKING = 8 + NETWORK_DENIAL_OF_SERVICE = 17 + CLOUD_SERVICE_DISCOVERY = 48 + STEAL_APPLICATION_ACCESS_TOKEN = 42 + ACCOUNT_ACCESS_REMOVAL = 51 + STEAL_WEB_SESSION_COOKIE = 25 + CREATE_OR_MODIFY_SYSTEM_PROCESS = 24 ABUSE_ELEVATION_CONTROL_MECHANISM = 34 - DEFAULT_ACCOUNTS = 35 + UNSECURED_CREDENTIALS = 13 + MODIFY_AUTHENTICATION_PROCESS = 28 + IMPAIR_DEFENSES = 31 + DISABLE_OR_MODIFY_TOOLS = 55 + EXFILTRATION_OVER_WEB_SERVICE = 20 + EXFILTRATION_TO_CLOUD_STORAGE = 21 + DYNAMIC_RESOLUTION = 12 + LATERAL_TOOL_TRANSFER = 41 + MODIFY_CLOUD_COMPUTE_INFRASTRUCTURE = 26 + CREATE_SNAPSHOT = 54 + CLOUD_INFRASTRUCTURE_DISCOVERY = 53 + OBTAIN_CAPABILITIES = 43 + ACTIVE_SCANNING = 1 + SCANNING_IP_BLOCKS = 2 + CONTAINER_AND_RESOURCE_DISCOVERY = 57 primary_tactic: Tactic = proto.Field( proto.ENUM, diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/org_policy.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/org_policy.py new file mode 100644 index 000000000000..5845b4634e2b --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/org_policy.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v1", + manifest={ + "OrgPolicy", + }, +) + + +class OrgPolicy(proto.Message): + r"""Contains information about the org policies associated with + the finding. + + Attributes: + name (str): + The resource name of the org policy. Example: + "organizations/{organization_id}/policies/{constraint_name}". + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/source.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/source.py index d166df568420..55b6df83177d 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/source.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/source.py @@ -58,9 +58,9 @@ class Source(proto.Message): mixed content (HTTP in HTTPS), and outdated or insecure libraries.". canonical_name (str): - The canonical name of the finding. It's either + The canonical name of the finding source. It's either "organizations/{organization_id}/sources/{source_id}", - "folders/{folder_id}/sources/{source_id}" or + "folders/{folder_id}/sources/{source_id}", or "projects/{project_number}/sources/{source_id}", depending on the closest CRM ancestor of the resource associated with the finding. diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/vulnerability.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/vulnerability.py index a9fea0e6bca2..80a1d551bd78 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/vulnerability.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/types/vulnerability.py @@ -17,6 +17,7 @@ from typing import MutableMapping, MutableSequence +from google.protobuf import timestamp_pb2 # type: ignore import proto # type: ignore __protobuf__ = proto.module( @@ -26,6 +27,8 @@ "Cve", "Reference", "Cvssv3", + "Package", + "SecurityBulletin", }, ) @@ -38,6 +41,14 @@ class Vulnerability(proto.Message): cve (google.cloud.securitycenter_v1.types.Cve): CVE stands for Common Vulnerabilities and Exposures (https://cve.mitre.org/about/) + offending_package (google.cloud.securitycenter_v1.types.Package): + The offending package is relevant to the + finding. + fixed_package (google.cloud.securitycenter_v1.types.Package): + The fixed package is relevant to the finding. + security_bulletin (google.cloud.securitycenter_v1.types.SecurityBulletin): + The security bulletin is relevant to this + finding. """ cve: "Cve" = proto.Field( @@ -45,11 +56,28 @@ class Vulnerability(proto.Message): number=1, message="Cve", ) + offending_package: "Package" = proto.Field( + proto.MESSAGE, + number=2, + message="Package", + ) + fixed_package: "Package" = proto.Field( + proto.MESSAGE, + number=3, + message="Package", + ) + security_bulletin: "SecurityBulletin" = proto.Field( + proto.MESSAGE, + number=4, + message="SecurityBulletin", + ) class Cve(proto.Message): - r"""CVE stands for Common Vulnerabilities and Exposures. - More information: https://cve.mitre.org + r"""CVE stands for Common Vulnerabilities and Exposures. Information + from the `CVE + record `__ that + describes this vulnerability. Attributes: id (str): @@ -66,8 +94,80 @@ class Cve(proto.Message): upstream_fix_available (bool): Whether upstream fix is available for the CVE. + impact (google.cloud.securitycenter_v1.types.Cve.RiskRating): + The potential impact of the vulnerability if + it was to be exploited. + exploitation_activity (google.cloud.securitycenter_v1.types.Cve.ExploitationActivity): + The exploitation activity of the + vulnerability in the wild. + observed_in_the_wild (bool): + Whether or not the vulnerability has been + observed in the wild. + zero_day (bool): + Whether or not the vulnerability was zero day + when the finding was published. """ + class RiskRating(proto.Enum): + r"""The possible values of impact of the vulnerability if it was + to be exploited. + + Values: + RISK_RATING_UNSPECIFIED (0): + Invalid or empty value. + LOW (1): + Exploitation would have little to no security + impact. + MEDIUM (2): + Exploitation would enable attackers to + perform activities, or could allow attackers to + have a direct impact, but would require + additional steps. + HIGH (3): + Exploitation would enable attackers to have a + notable direct impact without needing to + overcome any major mitigating factors. + CRITICAL (4): + Exploitation would fundamentally undermine + the security of affected systems, enable actors + to perform significant attacks with minimal + effort, with little to no mitigating factors to + overcome. + """ + RISK_RATING_UNSPECIFIED = 0 + LOW = 1 + MEDIUM = 2 + HIGH = 3 + CRITICAL = 4 + + class ExploitationActivity(proto.Enum): + r"""The possible values of exploitation activity of the + vulnerability in the wild. + + Values: + EXPLOITATION_ACTIVITY_UNSPECIFIED (0): + Invalid or empty value. + WIDE (1): + Exploitation has been reported or confirmed + to widely occur. + CONFIRMED (2): + Limited reported or confirmed exploitation + activities. + AVAILABLE (3): + Exploit is publicly available. + ANTICIPATED (4): + No known exploitation activity, but has a + high potential for exploitation. + NO_KNOWN (5): + No known exploitation activity. + """ + EXPLOITATION_ACTIVITY_UNSPECIFIED = 0 + WIDE = 1 + CONFIRMED = 2 + AVAILABLE = 3 + ANTICIPATED = 4 + NO_KNOWN = 5 + id: str = proto.Field( proto.STRING, number=1, @@ -86,6 +186,24 @@ class Cve(proto.Message): proto.BOOL, number=4, ) + impact: RiskRating = proto.Field( + proto.ENUM, + number=5, + enum=RiskRating, + ) + exploitation_activity: ExploitationActivity = proto.Field( + proto.ENUM, + number=6, + enum=ExploitationActivity, + ) + observed_in_the_wild: bool = proto.Field( + proto.BOOL, + number=7, + ) + zero_day: bool = proto.Field( + proto.BOOL, + number=8, + ) class Reference(proto.Message): @@ -350,4 +468,71 @@ class Impact(proto.Enum): ) +class Package(proto.Message): + r"""Package is a generic definition of a package. + + Attributes: + package_name (str): + The name of the package where the + vulnerability was detected. + cpe_uri (str): + The CPE URI where the vulnerability was + detected. + package_type (str): + Type of package, for example, os, maven, or + go. + package_version (str): + The version of the package. + """ + + package_name: str = proto.Field( + proto.STRING, + number=1, + ) + cpe_uri: str = proto.Field( + proto.STRING, + number=2, + ) + package_type: str = proto.Field( + proto.STRING, + number=3, + ) + package_version: str = proto.Field( + proto.STRING, + number=4, + ) + + +class SecurityBulletin(proto.Message): + r"""SecurityBulletin are notifications of vulnerabilities of + Google products. + + Attributes: + bulletin_id (str): + ID of the bulletin corresponding to the + vulnerability. + submission_time (google.protobuf.timestamp_pb2.Timestamp): + Submission time of this Security Bulletin. + suggested_upgrade_version (str): + This represents a version that the cluster + receiving this notification should be upgraded + to, based on its current version. For example, + 1.15.0 + """ + + bulletin_id: str = proto.Field( + proto.STRING, + number=1, + ) + submission_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + suggested_upgrade_version: str = proto.Field( + proto.STRING, + number=3, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/gapic_version.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/gapic_version.py index 484507c567a0..360a0d13ebdd 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/gapic_version.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.27.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/gapic_version.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/gapic_version.py index 484507c567a0..360a0d13ebdd 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/gapic_version.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.27.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/__init__.py new file mode 100644 index 000000000000..c64249b8bcfa --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/__init__.py @@ -0,0 +1,224 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from google.cloud.securitycenter_v2 import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.security_center import SecurityCenterAsyncClient, SecurityCenterClient +from .types.access import Access, Geolocation, ServiceAccountDelegationInfo +from .types.application import Application +from .types.attack_exposure import AttackExposure +from .types.attack_path import AttackPath +from .types.backup_disaster_recovery import BackupDisasterRecovery +from .types.bigquery_export import BigQueryExport +from .types.cloud_dlp_data_profile import CloudDlpDataProfile +from .types.cloud_dlp_inspection import CloudDlpInspection +from .types.compliance import Compliance +from .types.connection import Connection +from .types.contact_details import Contact, ContactDetails +from .types.container import Container +from .types.database import Database +from .types.exfiltration import ExfilResource, Exfiltration +from .types.external_system import ExternalSystem +from .types.file import File +from .types.finding import Finding +from .types.iam_binding import IamBinding +from .types.indicator import Indicator +from .types.kernel_rootkit import KernelRootkit +from .types.kubernetes import Kubernetes +from .types.label import Label +from .types.load_balancer import LoadBalancer +from .types.log_entry import CloudLoggingEntry, LogEntry +from .types.mitre_attack import MitreAttack +from .types.mute_config import MuteConfig +from .types.notification_config import NotificationConfig +from .types.notification_message import NotificationMessage +from .types.org_policy import OrgPolicy +from .types.process import EnvironmentVariable, Process +from .types.resource import Resource +from .types.resource_value_config import ResourceValue, ResourceValueConfig +from .types.security_marks import SecurityMarks +from .types.security_posture import SecurityPosture +from .types.securitycenter_service import ( + BatchCreateResourceValueConfigsRequest, + BatchCreateResourceValueConfigsResponse, + BulkMuteFindingsRequest, + BulkMuteFindingsResponse, + CreateBigQueryExportRequest, + CreateFindingRequest, + CreateMuteConfigRequest, + CreateNotificationConfigRequest, + CreateResourceValueConfigRequest, + CreateSourceRequest, + DeleteBigQueryExportRequest, + DeleteMuteConfigRequest, + DeleteNotificationConfigRequest, + DeleteResourceValueConfigRequest, + GetBigQueryExportRequest, + GetMuteConfigRequest, + GetNotificationConfigRequest, + GetResourceValueConfigRequest, + GetSimulationRequest, + GetSourceRequest, + GetValuedResourceRequest, + GroupFindingsRequest, + GroupFindingsResponse, + GroupResult, + ListAttackPathsRequest, + ListAttackPathsResponse, + ListBigQueryExportsRequest, + ListBigQueryExportsResponse, + ListFindingsRequest, + ListFindingsResponse, + ListMuteConfigsRequest, + ListMuteConfigsResponse, + ListNotificationConfigsRequest, + ListNotificationConfigsResponse, + ListResourceValueConfigsRequest, + ListResourceValueConfigsResponse, + ListSourcesRequest, + ListSourcesResponse, + ListValuedResourcesRequest, + ListValuedResourcesResponse, + SetFindingStateRequest, + SetMuteRequest, + UpdateBigQueryExportRequest, + UpdateExternalSystemRequest, + UpdateFindingRequest, + UpdateMuteConfigRequest, + UpdateNotificationConfigRequest, + UpdateResourceValueConfigRequest, + UpdateSecurityMarksRequest, + UpdateSourceRequest, +) +from .types.simulation import Simulation +from .types.source import Source +from .types.valued_resource import ResourceValueConfigMetadata, ValuedResource +from .types.vulnerability import ( + Cve, + Cvssv3, + Package, + Reference, + SecurityBulletin, + Vulnerability, +) + +__all__ = ( + "SecurityCenterAsyncClient", + "Access", + "Application", + "AttackExposure", + "AttackPath", + "BackupDisasterRecovery", + "BatchCreateResourceValueConfigsRequest", + "BatchCreateResourceValueConfigsResponse", + "BigQueryExport", + "BulkMuteFindingsRequest", + "BulkMuteFindingsResponse", + "CloudDlpDataProfile", + "CloudDlpInspection", + "CloudLoggingEntry", + "Compliance", + "Connection", + "Contact", + "ContactDetails", + "Container", + "CreateBigQueryExportRequest", + "CreateFindingRequest", + "CreateMuteConfigRequest", + "CreateNotificationConfigRequest", + "CreateResourceValueConfigRequest", + "CreateSourceRequest", + "Cve", + "Cvssv3", + "Database", + "DeleteBigQueryExportRequest", + "DeleteMuteConfigRequest", + "DeleteNotificationConfigRequest", + "DeleteResourceValueConfigRequest", + "EnvironmentVariable", + "ExfilResource", + "Exfiltration", + "ExternalSystem", + "File", + "Finding", + "Geolocation", + "GetBigQueryExportRequest", + "GetMuteConfigRequest", + "GetNotificationConfigRequest", + "GetResourceValueConfigRequest", + "GetSimulationRequest", + "GetSourceRequest", + "GetValuedResourceRequest", + "GroupFindingsRequest", + "GroupFindingsResponse", + "GroupResult", + "IamBinding", + "Indicator", + "KernelRootkit", + "Kubernetes", + "Label", + "ListAttackPathsRequest", + "ListAttackPathsResponse", + "ListBigQueryExportsRequest", + "ListBigQueryExportsResponse", + "ListFindingsRequest", + "ListFindingsResponse", + "ListMuteConfigsRequest", + "ListMuteConfigsResponse", + "ListNotificationConfigsRequest", + "ListNotificationConfigsResponse", + "ListResourceValueConfigsRequest", + "ListResourceValueConfigsResponse", + "ListSourcesRequest", + "ListSourcesResponse", + "ListValuedResourcesRequest", + "ListValuedResourcesResponse", + "LoadBalancer", + "LogEntry", + "MitreAttack", + "MuteConfig", + "NotificationConfig", + "NotificationMessage", + "OrgPolicy", + "Package", + "Process", + "Reference", + "Resource", + "ResourceValue", + "ResourceValueConfig", + "ResourceValueConfigMetadata", + "SecurityBulletin", + "SecurityCenterClient", + "SecurityMarks", + "SecurityPosture", + "ServiceAccountDelegationInfo", + "SetFindingStateRequest", + "SetMuteRequest", + "Simulation", + "Source", + "UpdateBigQueryExportRequest", + "UpdateExternalSystemRequest", + "UpdateFindingRequest", + "UpdateMuteConfigRequest", + "UpdateNotificationConfigRequest", + "UpdateResourceValueConfigRequest", + "UpdateSecurityMarksRequest", + "UpdateSourceRequest", + "ValuedResource", + "Vulnerability", +) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/gapic_metadata.json b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/gapic_metadata.json new file mode 100644 index 000000000000..517d51c03f32 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/gapic_metadata.json @@ -0,0 +1,628 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.securitycenter_v2", + "protoPackage": "google.cloud.securitycenter.v2", + "schema": "1.0", + "services": { + "SecurityCenter": { + "clients": { + "grpc": { + "libraryClient": "SecurityCenterClient", + "rpcs": { + "BatchCreateResourceValueConfigs": { + "methods": [ + "batch_create_resource_value_configs" + ] + }, + "BulkMuteFindings": { + "methods": [ + "bulk_mute_findings" + ] + }, + "CreateBigQueryExport": { + "methods": [ + "create_big_query_export" + ] + }, + "CreateFinding": { + "methods": [ + "create_finding" + ] + }, + "CreateMuteConfig": { + "methods": [ + "create_mute_config" + ] + }, + "CreateNotificationConfig": { + "methods": [ + "create_notification_config" + ] + }, + "CreateSource": { + "methods": [ + "create_source" + ] + }, + "DeleteBigQueryExport": { + "methods": [ + "delete_big_query_export" + ] + }, + "DeleteMuteConfig": { + "methods": [ + "delete_mute_config" + ] + }, + "DeleteNotificationConfig": { + "methods": [ + "delete_notification_config" + ] + }, + "DeleteResourceValueConfig": { + "methods": [ + "delete_resource_value_config" + ] + }, + "GetBigQueryExport": { + "methods": [ + "get_big_query_export" + ] + }, + "GetIamPolicy": { + "methods": [ + "get_iam_policy" + ] + }, + "GetMuteConfig": { + "methods": [ + "get_mute_config" + ] + }, + "GetNotificationConfig": { + "methods": [ + "get_notification_config" + ] + }, + "GetResourceValueConfig": { + "methods": [ + "get_resource_value_config" + ] + }, + "GetSimulation": { + "methods": [ + "get_simulation" + ] + }, + "GetSource": { + "methods": [ + "get_source" + ] + }, + "GetValuedResource": { + "methods": [ + "get_valued_resource" + ] + }, + "GroupFindings": { + "methods": [ + "group_findings" + ] + }, + "ListAttackPaths": { + "methods": [ + "list_attack_paths" + ] + }, + "ListBigQueryExports": { + "methods": [ + "list_big_query_exports" + ] + }, + "ListFindings": { + "methods": [ + "list_findings" + ] + }, + "ListMuteConfigs": { + "methods": [ + "list_mute_configs" + ] + }, + "ListNotificationConfigs": { + "methods": [ + "list_notification_configs" + ] + }, + "ListResourceValueConfigs": { + "methods": [ + "list_resource_value_configs" + ] + }, + "ListSources": { + "methods": [ + "list_sources" + ] + }, + "ListValuedResources": { + "methods": [ + "list_valued_resources" + ] + }, + "SetFindingState": { + "methods": [ + "set_finding_state" + ] + }, + "SetIamPolicy": { + "methods": [ + "set_iam_policy" + ] + }, + "SetMute": { + "methods": [ + "set_mute" + ] + }, + "TestIamPermissions": { + "methods": [ + "test_iam_permissions" + ] + }, + "UpdateBigQueryExport": { + "methods": [ + "update_big_query_export" + ] + }, + "UpdateExternalSystem": { + "methods": [ + "update_external_system" + ] + }, + "UpdateFinding": { + "methods": [ + "update_finding" + ] + }, + "UpdateMuteConfig": { + "methods": [ + "update_mute_config" + ] + }, + "UpdateNotificationConfig": { + "methods": [ + "update_notification_config" + ] + }, + "UpdateResourceValueConfig": { + "methods": [ + "update_resource_value_config" + ] + }, + "UpdateSecurityMarks": { + "methods": [ + "update_security_marks" + ] + }, + "UpdateSource": { + "methods": [ + "update_source" + ] + } + } + }, + "grpc-async": { + "libraryClient": "SecurityCenterAsyncClient", + "rpcs": { + "BatchCreateResourceValueConfigs": { + "methods": [ + "batch_create_resource_value_configs" + ] + }, + "BulkMuteFindings": { + "methods": [ + "bulk_mute_findings" + ] + }, + "CreateBigQueryExport": { + "methods": [ + "create_big_query_export" + ] + }, + "CreateFinding": { + "methods": [ + "create_finding" + ] + }, + "CreateMuteConfig": { + "methods": [ + "create_mute_config" + ] + }, + "CreateNotificationConfig": { + "methods": [ + "create_notification_config" + ] + }, + "CreateSource": { + "methods": [ + "create_source" + ] + }, + "DeleteBigQueryExport": { + "methods": [ + "delete_big_query_export" + ] + }, + "DeleteMuteConfig": { + "methods": [ + "delete_mute_config" + ] + }, + "DeleteNotificationConfig": { + "methods": [ + "delete_notification_config" + ] + }, + "DeleteResourceValueConfig": { + "methods": [ + "delete_resource_value_config" + ] + }, + "GetBigQueryExport": { + "methods": [ + "get_big_query_export" + ] + }, + "GetIamPolicy": { + "methods": [ + "get_iam_policy" + ] + }, + "GetMuteConfig": { + "methods": [ + "get_mute_config" + ] + }, + "GetNotificationConfig": { + "methods": [ + "get_notification_config" + ] + }, + "GetResourceValueConfig": { + "methods": [ + "get_resource_value_config" + ] + }, + "GetSimulation": { + "methods": [ + "get_simulation" + ] + }, + "GetSource": { + "methods": [ + "get_source" + ] + }, + "GetValuedResource": { + "methods": [ + "get_valued_resource" + ] + }, + "GroupFindings": { + "methods": [ + "group_findings" + ] + }, + "ListAttackPaths": { + "methods": [ + "list_attack_paths" + ] + }, + "ListBigQueryExports": { + "methods": [ + "list_big_query_exports" + ] + }, + "ListFindings": { + "methods": [ + "list_findings" + ] + }, + "ListMuteConfigs": { + "methods": [ + "list_mute_configs" + ] + }, + "ListNotificationConfigs": { + "methods": [ + "list_notification_configs" + ] + }, + "ListResourceValueConfigs": { + "methods": [ + "list_resource_value_configs" + ] + }, + "ListSources": { + "methods": [ + "list_sources" + ] + }, + "ListValuedResources": { + "methods": [ + "list_valued_resources" + ] + }, + "SetFindingState": { + "methods": [ + "set_finding_state" + ] + }, + "SetIamPolicy": { + "methods": [ + "set_iam_policy" + ] + }, + "SetMute": { + "methods": [ + "set_mute" + ] + }, + "TestIamPermissions": { + "methods": [ + "test_iam_permissions" + ] + }, + "UpdateBigQueryExport": { + "methods": [ + "update_big_query_export" + ] + }, + "UpdateExternalSystem": { + "methods": [ + "update_external_system" + ] + }, + "UpdateFinding": { + "methods": [ + "update_finding" + ] + }, + "UpdateMuteConfig": { + "methods": [ + "update_mute_config" + ] + }, + "UpdateNotificationConfig": { + "methods": [ + "update_notification_config" + ] + }, + "UpdateResourceValueConfig": { + "methods": [ + "update_resource_value_config" + ] + }, + "UpdateSecurityMarks": { + "methods": [ + "update_security_marks" + ] + }, + "UpdateSource": { + "methods": [ + "update_source" + ] + } + } + }, + "rest": { + "libraryClient": "SecurityCenterClient", + "rpcs": { + "BatchCreateResourceValueConfigs": { + "methods": [ + "batch_create_resource_value_configs" + ] + }, + "BulkMuteFindings": { + "methods": [ + "bulk_mute_findings" + ] + }, + "CreateBigQueryExport": { + "methods": [ + "create_big_query_export" + ] + }, + "CreateFinding": { + "methods": [ + "create_finding" + ] + }, + "CreateMuteConfig": { + "methods": [ + "create_mute_config" + ] + }, + "CreateNotificationConfig": { + "methods": [ + "create_notification_config" + ] + }, + "CreateSource": { + "methods": [ + "create_source" + ] + }, + "DeleteBigQueryExport": { + "methods": [ + "delete_big_query_export" + ] + }, + "DeleteMuteConfig": { + "methods": [ + "delete_mute_config" + ] + }, + "DeleteNotificationConfig": { + "methods": [ + "delete_notification_config" + ] + }, + "DeleteResourceValueConfig": { + "methods": [ + "delete_resource_value_config" + ] + }, + "GetBigQueryExport": { + "methods": [ + "get_big_query_export" + ] + }, + "GetIamPolicy": { + "methods": [ + "get_iam_policy" + ] + }, + "GetMuteConfig": { + "methods": [ + "get_mute_config" + ] + }, + "GetNotificationConfig": { + "methods": [ + "get_notification_config" + ] + }, + "GetResourceValueConfig": { + "methods": [ + "get_resource_value_config" + ] + }, + "GetSimulation": { + "methods": [ + "get_simulation" + ] + }, + "GetSource": { + "methods": [ + "get_source" + ] + }, + "GetValuedResource": { + "methods": [ + "get_valued_resource" + ] + }, + "GroupFindings": { + "methods": [ + "group_findings" + ] + }, + "ListAttackPaths": { + "methods": [ + "list_attack_paths" + ] + }, + "ListBigQueryExports": { + "methods": [ + "list_big_query_exports" + ] + }, + "ListFindings": { + "methods": [ + "list_findings" + ] + }, + "ListMuteConfigs": { + "methods": [ + "list_mute_configs" + ] + }, + "ListNotificationConfigs": { + "methods": [ + "list_notification_configs" + ] + }, + "ListResourceValueConfigs": { + "methods": [ + "list_resource_value_configs" + ] + }, + "ListSources": { + "methods": [ + "list_sources" + ] + }, + "ListValuedResources": { + "methods": [ + "list_valued_resources" + ] + }, + "SetFindingState": { + "methods": [ + "set_finding_state" + ] + }, + "SetIamPolicy": { + "methods": [ + "set_iam_policy" + ] + }, + "SetMute": { + "methods": [ + "set_mute" + ] + }, + "TestIamPermissions": { + "methods": [ + "test_iam_permissions" + ] + }, + "UpdateBigQueryExport": { + "methods": [ + "update_big_query_export" + ] + }, + "UpdateExternalSystem": { + "methods": [ + "update_external_system" + ] + }, + "UpdateFinding": { + "methods": [ + "update_finding" + ] + }, + "UpdateMuteConfig": { + "methods": [ + "update_mute_config" + ] + }, + "UpdateNotificationConfig": { + "methods": [ + "update_notification_config" + ] + }, + "UpdateResourceValueConfig": { + "methods": [ + "update_resource_value_config" + ] + }, + "UpdateSecurityMarks": { + "methods": [ + "update_security_marks" + ] + }, + "UpdateSource": { + "methods": [ + "update_source" + ] + } + } + } + } + } + } +} diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/gapic_version.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/gapic_version.py new file mode 100644 index 000000000000..360a0d13ebdd --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/py.typed b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/py.typed new file mode 100644 index 000000000000..23a44fc7e4ca --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-securitycenter package uses inline types. diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/__init__.py new file mode 100644 index 000000000000..2ca1ad835af4 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from .async_client import SecurityCenterAsyncClient +from .client import SecurityCenterClient + +__all__ = ( + "SecurityCenterClient", + "SecurityCenterAsyncClient", +) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/async_client.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/async_client.py new file mode 100644 index 000000000000..f52aaf06f809 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/async_client.py @@ -0,0 +1,5667 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from collections import OrderedDict +import functools +import re +from typing import ( + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.securitycenter_v2 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.iam.v1 import iam_policy_pb2 # type: ignore +from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.securitycenter_v2.services.security_center import pagers +from google.cloud.securitycenter_v2.types import ( + access, + application, + attack_exposure, + attack_path, + backup_disaster_recovery, + bigquery_export, + cloud_dlp_data_profile, + cloud_dlp_inspection, + compliance, + connection, + container, + database, + exfiltration, +) +from google.cloud.securitycenter_v2.types import ( + iam_binding, + indicator, + kernel_rootkit, + kubernetes, + load_balancer, + log_entry, + mitre_attack, +) +from google.cloud.securitycenter_v2.types import ( + security_posture, + securitycenter_service, + simulation, +) +from google.cloud.securitycenter_v2.types import external_system as gcs_external_system +from google.cloud.securitycenter_v2.types import ( + notification_config as gcs_notification_config, +) +from google.cloud.securitycenter_v2.types import ( + resource_value_config as gcs_resource_value_config, +) +from google.cloud.securitycenter_v2.types import security_marks as gcs_security_marks +from google.cloud.securitycenter_v2.types import file +from google.cloud.securitycenter_v2.types import finding +from google.cloud.securitycenter_v2.types import finding as gcs_finding +from google.cloud.securitycenter_v2.types import mute_config +from google.cloud.securitycenter_v2.types import mute_config as gcs_mute_config +from google.cloud.securitycenter_v2.types import notification_config +from google.cloud.securitycenter_v2.types import org_policy, process +from google.cloud.securitycenter_v2.types import resource_value_config +from google.cloud.securitycenter_v2.types import security_marks +from google.cloud.securitycenter_v2.types import source +from google.cloud.securitycenter_v2.types import source as gcs_source +from google.cloud.securitycenter_v2.types import valued_resource, vulnerability + +from .client import SecurityCenterClient +from .transports.base import DEFAULT_CLIENT_INFO, SecurityCenterTransport +from .transports.grpc_asyncio import SecurityCenterGrpcAsyncIOTransport + + +class SecurityCenterAsyncClient: + """V2 APIs for Security Center service.""" + + _client: SecurityCenterClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = SecurityCenterClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = SecurityCenterClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = SecurityCenterClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = SecurityCenterClient._DEFAULT_UNIVERSE + + attack_path_path = staticmethod(SecurityCenterClient.attack_path_path) + parse_attack_path_path = staticmethod(SecurityCenterClient.parse_attack_path_path) + big_query_export_path = staticmethod(SecurityCenterClient.big_query_export_path) + parse_big_query_export_path = staticmethod( + SecurityCenterClient.parse_big_query_export_path + ) + dlp_job_path = staticmethod(SecurityCenterClient.dlp_job_path) + parse_dlp_job_path = staticmethod(SecurityCenterClient.parse_dlp_job_path) + external_system_path = staticmethod(SecurityCenterClient.external_system_path) + parse_external_system_path = staticmethod( + SecurityCenterClient.parse_external_system_path + ) + finding_path = staticmethod(SecurityCenterClient.finding_path) + parse_finding_path = staticmethod(SecurityCenterClient.parse_finding_path) + mute_config_path = staticmethod(SecurityCenterClient.mute_config_path) + parse_mute_config_path = staticmethod(SecurityCenterClient.parse_mute_config_path) + notification_config_path = staticmethod( + SecurityCenterClient.notification_config_path + ) + parse_notification_config_path = staticmethod( + SecurityCenterClient.parse_notification_config_path + ) + policy_path = staticmethod(SecurityCenterClient.policy_path) + parse_policy_path = staticmethod(SecurityCenterClient.parse_policy_path) + resource_value_config_path = staticmethod( + SecurityCenterClient.resource_value_config_path + ) + parse_resource_value_config_path = staticmethod( + SecurityCenterClient.parse_resource_value_config_path + ) + security_marks_path = staticmethod(SecurityCenterClient.security_marks_path) + parse_security_marks_path = staticmethod( + SecurityCenterClient.parse_security_marks_path + ) + simulation_path = staticmethod(SecurityCenterClient.simulation_path) + parse_simulation_path = staticmethod(SecurityCenterClient.parse_simulation_path) + source_path = staticmethod(SecurityCenterClient.source_path) + parse_source_path = staticmethod(SecurityCenterClient.parse_source_path) + table_data_profile_path = staticmethod(SecurityCenterClient.table_data_profile_path) + parse_table_data_profile_path = staticmethod( + SecurityCenterClient.parse_table_data_profile_path + ) + topic_path = staticmethod(SecurityCenterClient.topic_path) + parse_topic_path = staticmethod(SecurityCenterClient.parse_topic_path) + valued_resource_path = staticmethod(SecurityCenterClient.valued_resource_path) + parse_valued_resource_path = staticmethod( + SecurityCenterClient.parse_valued_resource_path + ) + common_billing_account_path = staticmethod( + SecurityCenterClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + SecurityCenterClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(SecurityCenterClient.common_folder_path) + parse_common_folder_path = staticmethod( + SecurityCenterClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + SecurityCenterClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + SecurityCenterClient.parse_common_organization_path + ) + common_project_path = staticmethod(SecurityCenterClient.common_project_path) + parse_common_project_path = staticmethod( + SecurityCenterClient.parse_common_project_path + ) + common_location_path = staticmethod(SecurityCenterClient.common_location_path) + parse_common_location_path = staticmethod( + SecurityCenterClient.parse_common_location_path + ) + + @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: + SecurityCenterAsyncClient: The constructed client. + """ + return SecurityCenterClient.from_service_account_info.__func__(SecurityCenterAsyncClient, 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: + SecurityCenterAsyncClient: The constructed client. + """ + return SecurityCenterClient.from_service_account_file.__func__(SecurityCenterAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return SecurityCenterClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> SecurityCenterTransport: + """Returns the transport used by the client instance. + + Returns: + SecurityCenterTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = functools.partial( + type(SecurityCenterClient).get_transport_class, type(SecurityCenterClient) + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, SecurityCenterTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the security center async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + 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, ~.SecurityCenterTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = SecurityCenterClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def batch_create_resource_value_configs( + self, + request: Optional[ + Union[securitycenter_service.BatchCreateResourceValueConfigsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + requests: Optional[ + MutableSequence[securitycenter_service.CreateResourceValueConfigRequest] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.BatchCreateResourceValueConfigsResponse: + r"""Creates a ResourceValueConfig for an organization. + Maps user's tags to difference resource values for use + by the attack path simulation. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_batch_create_resource_value_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + requests = securitycenter_v2.CreateResourceValueConfigRequest() + requests.parent = "parent_value" + requests.resource_value_config.tag_values = ['tag_values_value1', 'tag_values_value2'] + + request = securitycenter_v2.BatchCreateResourceValueConfigsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = await client.batch_create_resource_value_configs(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.BatchCreateResourceValueConfigsRequest, dict]]): + The request object. Request message to create multiple + resource value configs + parent (:class:`str`): + Required. Resource name of the new + ResourceValueConfig's parent. The parent + field in the + CreateResourceValueConfigRequest + messages must either be empty or match + this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (:class:`MutableSequence[google.cloud.securitycenter_v2.types.CreateResourceValueConfigRequest]`): + Required. The resource value configs + to be created. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.BatchCreateResourceValueConfigsResponse: + Response message for + BatchCreateResourceValueConfigs + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, requests]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.BatchCreateResourceValueConfigsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_create_resource_value_configs, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def bulk_mute_findings( + self, + request: Optional[ + Union[securitycenter_service.BulkMuteFindingsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Kicks off an LRO to bulk mute findings for a parent + based on a filter. If no location is specified, findings + are muted in global. The parent can be either an + organization, folder, or project. The findings matched + by the filter will be muted after the LRO is done. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_bulk_mute_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.BulkMuteFindingsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.bulk_mute_findings(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.BulkMuteFindingsRequest, dict]]): + The request object. Request message for bulk findings + update. + Note: + + 1. If multiple bulk update requests + match the same resource, the order + in which they get executed is not + defined. + 2. Once a bulk operation is started, + there is no way to stop it. + parent (:class:`str`): + Required. The parent, at which bulk action needs to be + applied. If no location is specified, findings are + updated in global. The following list shows some + examples: + + - ``organizations/[organization_id]`` + - ``organizations/[organization_id]/locations/[location_id]`` + - ``folders/[folder_id]`` + - ``folders/[folder_id]/locations/[location_id]`` + - ``projects/[project_id]`` + - ``projects/[project_id]/locations/[location_id]`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.securitycenter_v2.types.BulkMuteFindingsResponse` + The response to a BulkMute request. Contains the LRO + information. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.BulkMuteFindingsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.bulk_mute_findings, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + securitycenter_service.BulkMuteFindingsResponse, + metadata_type=empty_pb2.Empty, + ) + + # Done; return the response. + return response + + async def create_big_query_export( + self, + request: Optional[ + Union[securitycenter_service.CreateBigQueryExportRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + big_query_export: Optional[bigquery_export.BigQueryExport] = None, + big_query_export_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bigquery_export.BigQueryExport: + r"""Creates a BigQuery export. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_create_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateBigQueryExportRequest( + parent="parent_value", + big_query_export_id="big_query_export_id_value", + ) + + # Make the request + response = await client.create_big_query_export(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.CreateBigQueryExportRequest, dict]]): + The request object. Request message for creating a + BigQuery export. + parent (:class:`str`): + Required. The name of the parent resource of the new + BigQuery export. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + big_query_export (:class:`google.cloud.securitycenter_v2.types.BigQueryExport`): + Required. The BigQuery export being + created. + + This corresponds to the ``big_query_export`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + big_query_export_id (:class:`str`): + Required. Unique identifier provided + by the client within the parent scope. + It must consist of only lowercase + letters, numbers, and hyphens, must + start with a letter, must end with + either a letter or a number, and must be + 63 characters or less. + + This corresponds to the ``big_query_export_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.BigQueryExport: + Configures how to deliver Findings to + BigQuery Instance. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, big_query_export, big_query_export_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.CreateBigQueryExportRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if big_query_export is not None: + request.big_query_export = big_query_export + if big_query_export_id is not None: + request.big_query_export_id = big_query_export_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_big_query_export, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_finding( + self, + request: Optional[ + Union[securitycenter_service.CreateFindingRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + finding: Optional[gcs_finding.Finding] = None, + finding_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_finding.Finding: + r"""Creates a finding in a location. The corresponding + source must exist for finding creation to succeed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_create_finding(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateFindingRequest( + parent="parent_value", + finding_id="finding_id_value", + ) + + # Make the request + response = await client.create_finding(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.CreateFindingRequest, dict]]): + The request object. Request message for creating a + finding. + parent (:class:`str`): + Required. Resource name of the new finding's parent. The + following list shows some examples of the format: + + ``organizations/[organization_id]/sources/[source_id]`` + + + ``organizations/[organization_id]/sources/[source_id]/locations/[location_id]`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + finding (:class:`google.cloud.securitycenter_v2.types.Finding`): + Required. The Finding being created. The name and + security_marks will be ignored as they are both output + only fields on this resource. + + This corresponds to the ``finding`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + finding_id (:class:`str`): + Required. Unique identifier provided + by the client within the parent scope. + It must be alphanumeric and less than or + equal to 32 characters and greater than + 0 characters in length. + + This corresponds to the ``finding_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, finding, finding_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.CreateFindingRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if finding is not None: + request.finding = finding + if finding_id is not None: + request.finding_id = finding_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_finding, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_mute_config( + self, + request: Optional[ + Union[securitycenter_service.CreateMuteConfigRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + mute_config: Optional[gcs_mute_config.MuteConfig] = None, + mute_config_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_mute_config.MuteConfig: + r"""Creates a mute config. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_create_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + mute_config = securitycenter_v2.MuteConfig() + mute_config.filter = "filter_value" + mute_config.type_ = "STATIC" + + request = securitycenter_v2.CreateMuteConfigRequest( + parent="parent_value", + mute_config=mute_config, + mute_config_id="mute_config_id_value", + ) + + # Make the request + response = await client.create_mute_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.CreateMuteConfigRequest, dict]]): + The request object. Request message for creating a mute + config. + parent (:class:`str`): + Required. Resource name of the new mute configs's + parent. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mute_config (:class:`google.cloud.securitycenter_v2.types.MuteConfig`): + Required. The mute config being + created. + + This corresponds to the ``mute_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mute_config_id (:class:`str`): + Required. Unique identifier provided + by the client within the parent scope. + It must consist of only lowercase + letters, numbers, and hyphens, must + start with a letter, must end with + either a letter or a number, and must be + 63 characters or less. + + This corresponds to the ``mute_config_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.MuteConfig: + A mute config is a Cloud SCC resource + that contains the configuration to mute + create/update events of findings. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, mute_config, mute_config_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.CreateMuteConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if mute_config is not None: + request.mute_config = mute_config + if mute_config_id is not None: + request.mute_config_id = mute_config_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_mute_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_notification_config( + self, + request: Optional[ + Union[securitycenter_service.CreateNotificationConfigRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + notification_config: Optional[ + gcs_notification_config.NotificationConfig + ] = None, + config_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_notification_config.NotificationConfig: + r"""Creates a notification config. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_create_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateNotificationConfigRequest( + parent="parent_value", + config_id="config_id_value", + ) + + # Make the request + response = await client.create_notification_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.CreateNotificationConfigRequest, dict]]): + The request object. Request message for creating a + notification config. + parent (:class:`str`): + Required. Resource name of the new notification config's + parent. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + notification_config (:class:`google.cloud.securitycenter_v2.types.NotificationConfig`): + Required. The notification config + being created. The name and the service + account will be ignored as they are both + output only fields on this resource. + + This corresponds to the ``notification_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + config_id (:class:`str`): + Required. + Unique identifier provided by the client + within the parent scope. It must be + between 1 and 128 characters and contain + alphanumeric characters, underscores, or + hyphens only. + + This corresponds to the ``config_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.NotificationConfig: + Cloud Security Command Center (Cloud + SCC) notification configs. + A notification config is a Cloud SCC + resource that contains the configuration + to send notifications for create/update + events of findings, assets and etc. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, notification_config, config_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.CreateNotificationConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if notification_config is not None: + request.notification_config = notification_config + if config_id is not None: + request.config_id = config_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_notification_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_source( + self, + request: Optional[ + Union[securitycenter_service.CreateSourceRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + source: Optional[gcs_source.Source] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_source.Source: + r"""Creates a source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_create_source(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateSourceRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_source(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.CreateSourceRequest, dict]]): + The request object. Request message for creating a + source. + parent (:class:`str`): + Required. Resource name of the new source's parent. Its + format should be "organizations/[organization_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + source (:class:`google.cloud.securitycenter_v2.types.Source`): + Required. The Source being created, only the + display_name and description will be used. All other + fields will be ignored. + + This corresponds to the ``source`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Source: + Security Command Center finding + source. A finding source is an entity or + a mechanism that can produce a finding. + A source is like a container of findings + that come from the same scanner, logger, + monitor, and other tools. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, source]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.CreateSourceRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if source is not None: + request.source = source + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_source, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_big_query_export( + self, + request: Optional[ + Union[securitycenter_service.DeleteBigQueryExportRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes an existing BigQuery export. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_delete_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteBigQueryExportRequest( + name="name_value", + ) + + # Make the request + await client.delete_big_query_export(request=request) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.DeleteBigQueryExportRequest, dict]]): + The request object. Request message for deleting a + BigQuery export. + name (:class:`str`): + Required. The name of the BigQuery export to delete. The + following list shows some examples of the format: + + - + + ``organizations/{organization}/locations/{location}/bigQueryExports/{export_id}`` + + - ``folders/{folder}/locations/{location}/bigQueryExports/{export_id}`` + - ``projects/{project}/locations/{location}/bigQueryExports/{export_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.DeleteBigQueryExportRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_big_query_export, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def delete_mute_config( + self, + request: Optional[ + Union[securitycenter_service.DeleteMuteConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes an existing mute config. If no location is + specified, default is global. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_delete_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteMuteConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_mute_config(request=request) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.DeleteMuteConfigRequest, dict]]): + The request object. Request message for deleting a mute + config. If no location is specified, + default is global. + name (:class:`str`): + Required. Name of the mute config to delete. The + following list shows some examples of the format: + + - ``organizations/{organization}/muteConfigs/{config_id}`` + - + + ``organizations/{organization}/locations/{location}/muteConfigs/{config_id}`` + + - ``folders/{folder}/muteConfigs/{config_id}`` + - ``folders/{folder}/locations/{location}/muteConfigs/{config_id}`` + - ``projects/{project}/muteConfigs/{config_id}`` + - ``projects/{project}/locations/{location}/muteConfigs/{config_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.DeleteMuteConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_mute_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def delete_notification_config( + self, + request: Optional[ + Union[securitycenter_service.DeleteNotificationConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a notification config. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_delete_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteNotificationConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_notification_config(request=request) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.DeleteNotificationConfigRequest, dict]]): + The request object. Request message for deleting a + notification config. + name (:class:`str`): + Required. Name of the notification config to delete. The + following list shows some examples of the format: + + - + + ``organizations/[organization_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + + ``folders/[folder_id]/locations/[location_id]notificationConfigs/[config_id]`` + + + ``projects/[project_id]/locations/[location_id]notificationConfigs/[config_id]`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.DeleteNotificationConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_notification_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def delete_resource_value_config( + self, + request: Optional[ + Union[securitycenter_service.DeleteResourceValueConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a ResourceValueConfig. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_delete_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteResourceValueConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_resource_value_config(request=request) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.DeleteResourceValueConfigRequest, dict]]): + The request object. Request message to delete resource + value config + name (:class:`str`): + Required. Name of the + ResourceValueConfig to delete + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.DeleteResourceValueConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_resource_value_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_big_query_export( + self, + request: Optional[ + Union[securitycenter_service.GetBigQueryExportRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bigquery_export.BigQueryExport: + r"""Gets a BigQuery export. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_get_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetBigQueryExportRequest( + name="name_value", + ) + + # Make the request + response = await client.get_big_query_export(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.GetBigQueryExportRequest, dict]]): + The request object. Request message for retrieving a + BigQuery export. + name (:class:`str`): + Required. Name of the BigQuery export to retrieve. The + following list shows some examples of the format: + + - + + ``organizations/{organization}/locations/{location}/bigQueryExports/{export_id}`` + + - ``folders/{folder}/locations/{location}/bigQueryExports/{export_id}`` + - ``projects/{project}locations/{location}//bigQueryExports/{export_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.BigQueryExport: + Configures how to deliver Findings to + BigQuery Instance. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.GetBigQueryExportRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_big_query_export, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_simulation( + self, + request: Optional[ + Union[securitycenter_service.GetSimulationRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> simulation.Simulation: + r"""Get the simulation by name or the latest simulation + for the given organization. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_get_simulation(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetSimulationRequest( + name="name_value", + ) + + # Make the request + response = await client.get_simulation(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.GetSimulationRequest, dict]]): + The request object. Request message for getting + simulation. Simulation name can include + "latest" to retrieve the latest + simulation For example, + "organizations/123/simulations/latest". + name (:class:`str`): + Required. The organization name or + simulation name of this simulation + Valid format: + + "organizations/{organization}/simulations/latest" + "organizations/{organization}/simulations/{simulation}" + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Simulation: + Attack path simulation + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.GetSimulationRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_simulation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_valued_resource( + self, + request: Optional[ + Union[securitycenter_service.GetValuedResourceRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> valued_resource.ValuedResource: + r"""Get the valued resource by name + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_get_valued_resource(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetValuedResourceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_valued_resource(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.GetValuedResourceRequest, dict]]): + The request object. Request message for getting a valued + resource. + name (:class:`str`): + Required. The name of this valued resource + + Valid format: + "organizations/{organization}/simulations/{simulation}/valuedResources/{valued_resource}" + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.ValuedResource: + A resource that is determined to have + value to a user's system + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.GetValuedResourceRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_valued_resource, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_iam_policy( + self, + request: Optional[Union[iam_policy_pb2.GetIamPolicyRequest, dict]] = None, + *, + resource: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> policy_pb2.Policy: + r"""Gets the access control policy on the specified + Source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + from google.iam.v1 import iam_policy_pb2 # type: ignore + + async def sample_get_iam_policy(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = iam_policy_pb2.GetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = await client.get_iam_policy(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]]): + The request object. Request message for ``GetIamPolicy`` method. + resource (:class:`str`): + REQUIRED: The resource for which the + policy is being requested. See the + operation documentation for the + appropriate value for this field. + + This corresponds to the ``resource`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.iam.v1.policy_pb2.Policy: + An Identity and Access Management (IAM) policy, which specifies access + controls for Google Cloud resources. + + A Policy is a collection of bindings. A binding binds + one or more members, or principals, to a single role. + Principals can be user accounts, service accounts, + Google groups, and domains (such as G Suite). A role + is a named list of permissions; each role can be an + IAM predefined role or a user-created custom role. + + For some types of Google Cloud resources, a binding + can also specify a condition, which is a logical + expression that allows access to a resource only if + the expression evaluates to true. A condition can add + constraints based on attributes of the request, the + resource, or both. To learn which resources support + conditions in their IAM policies, see the [IAM + documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies). + + **JSON example:** + + :literal:`\` { "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')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \` + + **YAML example:** + + :literal:`\` 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') etag: BwWWja0YfJA= version: 3`\ \` + + For a description of IAM and its features, see the + [IAM + documentation](\ https://cloud.google.com/iam/docs/). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = iam_policy_pb2.GetIamPolicyRequest(**request) + elif not request: + request = iam_policy_pb2.GetIamPolicyRequest( + resource=resource, + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_iam_policy, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_mute_config( + self, + request: Optional[ + Union[securitycenter_service.GetMuteConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> mute_config.MuteConfig: + r"""Gets a mute config. If no location is specified, + default is global. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_get_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetMuteConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_mute_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.GetMuteConfigRequest, dict]]): + The request object. Request message for retrieving a mute + config. If no location is specified, + default is global. + name (:class:`str`): + Required. Name of the mute config to retrieve. The + following list shows some examples of the format: + + - ``organizations/{organization}/muteConfigs/{config_id}`` + - + + ``organizations/{organization}/locations/{location}/muteConfigs/{config_id}`` + + - ``folders/{folder}/muteConfigs/{config_id}`` + - ``folders/{folder}/locations/{location}/muteConfigs/{config_id}`` + - ``projects/{project}/muteConfigs/{config_id}`` + - ``projects/{project}/locations/{location}/muteConfigs/{config_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.MuteConfig: + A mute config is a Cloud SCC resource + that contains the configuration to mute + create/update events of findings. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.GetMuteConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_mute_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_notification_config( + self, + request: Optional[ + Union[securitycenter_service.GetNotificationConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> notification_config.NotificationConfig: + r"""Gets a notification config. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_get_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetNotificationConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_notification_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.GetNotificationConfigRequest, dict]]): + The request object. Request message for getting a + notification config. + name (:class:`str`): + Required. Name of the notification config to get. The + following list shows some examples of the format: + + - + + ``organizations/[organization_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + + ``folders/[folder_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + + ``projects/[project_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.NotificationConfig: + Cloud Security Command Center (Cloud + SCC) notification configs. + A notification config is a Cloud SCC + resource that contains the configuration + to send notifications for create/update + events of findings, assets and etc. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.GetNotificationConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_notification_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_resource_value_config( + self, + request: Optional[ + Union[securitycenter_service.GetResourceValueConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource_value_config.ResourceValueConfig: + r"""Gets a ResourceValueConfig. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_get_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetResourceValueConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_resource_value_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.GetResourceValueConfigRequest, dict]]): + The request object. Request message to get resource value + config + name (:class:`str`): + Required. Name of the resource value config to retrieve. + Its format is + organizations/{organization}/resourceValueConfigs/{config_id}. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.ResourceValueConfig: + A resource value config (RVC) is a + mapping configuration of user's + resources to resource values. Used in + Attack path simulations. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.GetResourceValueConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_resource_value_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_source( + self, + request: Optional[Union[securitycenter_service.GetSourceRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> source.Source: + r"""Gets a source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_get_source(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetSourceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_source(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.GetSourceRequest, dict]]): + The request object. Request message for getting a source. + name (:class:`str`): + Required. Relative resource name of the source. Its + format is + "organizations/[organization_id]/source/[source_id]". + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Source: + Security Command Center finding + source. A finding source is an entity or + a mechanism that can produce a finding. + A source is like a container of findings + that come from the same scanner, logger, + monitor, and other tools. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.GetSourceRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_source, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def group_findings( + self, + request: Optional[ + Union[securitycenter_service.GroupFindingsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + group_by: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.GroupFindingsAsyncPager: + r"""Filters an organization or source's findings and groups them by + their specified properties in a location. If no location is + specified, findings are assumed to be in global + + To group across all sources provide a ``-`` as the source id. + The following list shows some examples: + + - ``/v2/organizations/{organization_id}/sources/-/findings`` + - + + ``/v2/organizations/{organization_id}/sources/-/locations/{location_id}/findings`` + + - ``/v2/folders/{folder_id}/sources/-/findings`` + - ``/v2/folders/{folder_id}/sources/-/locations/{location_id}/findings`` + - ``/v2/projects/{project_id}/sources/-/findings`` + - ``/v2/projects/{project_id}/sources/-/locations/{location_id}/findings`` + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_group_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GroupFindingsRequest( + parent="parent_value", + group_by="group_by_value", + ) + + # Make the request + page_result = client.group_findings(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.GroupFindingsRequest, dict]]): + The request object. Request message for grouping by + findings. + parent (:class:`str`): + Required. Name of the source to groupBy. If no location + is specified, finding is assumed to be in global. The + following list shows some examples: + + - ``organizations/[organization_id]/sources/[source_id]`` + - + + ``organizations/[organization_id]/sources/[source_id]/locations/[location_id]`` + + - ``folders/[folder_id]/sources/[source_id]`` + - ``folders/[folder_id]/sources/[source_id]/locations/[location_id]`` + - ``projects/[project_id]/sources/[source_id]`` + - ``projects/[project_id]/sources/[source_id]/locations/[location_id]`` + + To groupBy across all sources provide a source_id of + ``-``. The following list shows some examples: + + - ``organizations/{organization_id}/sources/-`` + - ``organizations/{organization_id}/sources/-/locations/[location_id]`` + - ``folders/{folder_id}/sources/-`` + - ``folders/{folder_id}/sources/-/locations/[location_id]`` + - ``projects/{project_id}/sources/-`` + - ``projects/{project_id}/sources/-/locations/[location_id]`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + group_by (:class:`str`): + Required. Expression that defines what assets fields to + use for grouping. The string value should follow SQL + syntax: comma separated list of fields. For example: + "parent,resource_name". + + The following fields are supported: + + - resource_name + - category + - state + - parent + - severity + + This corresponds to the ``group_by`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.GroupFindingsAsyncPager: + Response message for group by + findings. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, group_by]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.GroupFindingsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if group_by is not None: + request.group_by = group_by + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.group_findings, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.GroupFindingsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_attack_paths( + self, + request: Optional[ + Union[securitycenter_service.ListAttackPathsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListAttackPathsAsyncPager: + r"""Lists the attack paths for a set of simulation + results or valued resources and filter. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_list_attack_paths(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListAttackPathsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_attack_paths(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.ListAttackPathsRequest, dict]]): + The request object. Request message for listing the + attack paths for a given simulation or + valued resource. + parent (:class:`str`): + Required. Name of parent to list attack paths. + + Valid formats: "organizations/{organization}", + "organizations/{organization}/simulations/{simulation}" + "organizations/{organization}/simulations/{simulation}/attackExposureResults/{attack_exposure_result_v2}" + "organizations/{organization}/simulations/{simulation}/valuedResources/{valued_resource}" + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListAttackPathsAsyncPager: + Response message for listing the + attack paths for a given simulation or + valued resource. + + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.ListAttackPathsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_attack_paths, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListAttackPathsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_big_query_exports( + self, + request: Optional[ + Union[securitycenter_service.ListBigQueryExportsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListBigQueryExportsAsyncPager: + r"""Lists BigQuery exports. Note that when requesting + BigQuery exports at a given level all exports under that + level are also returned e.g. if requesting BigQuery + exports under a folder, then all BigQuery exports + immediately under the folder plus the ones created under + the projects within the folder are returned. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_list_big_query_exports(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListBigQueryExportsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_big_query_exports(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.ListBigQueryExportsRequest, dict]]): + The request object. Request message for listing BigQuery + exports at a given scope e.g. + organization, folder or project. + parent (:class:`str`): + Required. The parent, which owns the collection of + BigQuery exports. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListBigQueryExportsAsyncPager: + Response message for listing BigQuery + exports. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.ListBigQueryExportsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_big_query_exports, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListBigQueryExportsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_findings( + self, + request: Optional[ + Union[securitycenter_service.ListFindingsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListFindingsAsyncPager: + r"""Lists an organization or source's findings. + + To list across all sources for a given location provide a ``-`` + as the source id. If no location is specified, finding are + assumed to be in global. The following list shows some examples: + + - ``/v2/organizations/{organization_id}/sources/-/findings`` + - + + ``/v2/organizations/{organization_id}/sources/-/locations/{location_id}/findings`` + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_list_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListFindingsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_findings(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.ListFindingsRequest, dict]]): + The request object. Request message for listing findings. + parent (:class:`str`): + Required. Name of the source the findings belong to. If + no location is specified, the default is global. The + following list shows some examples: + + - ``organizations/[organization_id]/sources/[source_id]`` + - + + ``organizations/[organization_id]/sources/[source_id]/locations/[location_id]`` + + - ``folders/[folder_id]/sources/[source_id]`` + - ``folders/[folder_id]/sources/[source_id]/locations/[location_id]`` + - ``projects/[project_id]/sources/[source_id]`` + - ``projects/[project_id]/sources/[source_id]/locations/[location_id]`` + + To list across all sources provide a source_id of ``-``. + The following list shows some examples: + + - ``organizations/{organization_id}/sources/-`` + - ``organizations/{organization_id}/sources/-/locations/{location_id}`` + - ``folders/{folder_id}/sources/-`` + - ``folders/{folder_id}/sources/-locations/{location_id}`` + - ``projects/{projects_id}/sources/-`` + - ``projects/{projects_id}/sources/-/locations/{location_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListFindingsAsyncPager: + Response message for listing + findings. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.ListFindingsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_findings, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListFindingsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_mute_configs( + self, + request: Optional[ + Union[securitycenter_service.ListMuteConfigsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListMuteConfigsAsyncPager: + r"""Lists mute configs. If no location is specified, + default is global. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_list_mute_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListMuteConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_mute_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.ListMuteConfigsRequest, dict]]): + The request object. Request message for listing mute + configs at a given scope e.g. + organization, folder or project. If no + location is specified, default is + global. + parent (:class:`str`): + Required. The parent, which owns the collection of mute + configs. Its format is + "organizations/[organization_id]", + "folders/[folder_id]", "projects/[project_id]", + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListMuteConfigsAsyncPager: + Response message for listing mute + configs. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.ListMuteConfigsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_mute_configs, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListMuteConfigsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_notification_configs( + self, + request: Optional[ + Union[securitycenter_service.ListNotificationConfigsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListNotificationConfigsAsyncPager: + r"""Lists notification configs. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_list_notification_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListNotificationConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_notification_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.ListNotificationConfigsRequest, dict]]): + The request object. Request message for listing + notification configs. + parent (:class:`str`): + Required. The name of the parent in which to list the + notification configurations. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListNotificationConfigsAsyncPager: + Response message for listing + notification configs. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.ListNotificationConfigsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_notification_configs, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListNotificationConfigsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_resource_value_configs( + self, + request: Optional[ + Union[securitycenter_service.ListResourceValueConfigsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListResourceValueConfigsAsyncPager: + r"""Lists all ResourceValueConfigs. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_list_resource_value_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListResourceValueConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_resource_value_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.ListResourceValueConfigsRequest, dict]]): + The request object. Request message to list resource + value configs of a parent + parent (:class:`str`): + Required. The parent, which owns the collection of + resource value configs. Its format is + "organizations/[organization_id]" + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListResourceValueConfigsAsyncPager: + Response message to list resource + value configs + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.ListResourceValueConfigsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_resource_value_configs, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListResourceValueConfigsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_sources( + self, + request: Optional[ + Union[securitycenter_service.ListSourcesRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListSourcesAsyncPager: + r"""Lists all sources belonging to an organization. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_list_sources(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListSourcesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_sources(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.ListSourcesRequest, dict]]): + The request object. Request message for listing sources. + parent (:class:`str`): + Required. Resource name of the parent of sources to + list. Its format should be + "organizations/[organization_id]", + "folders/[folder_id]", or "projects/[project_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListSourcesAsyncPager: + Response message for listing sources. + + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.ListSourcesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_sources, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListSourcesAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_valued_resources( + self, + request: Optional[ + Union[securitycenter_service.ListValuedResourcesRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListValuedResourcesAsyncPager: + r"""Lists the valued resources for a set of simulation + results and filter. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_list_valued_resources(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListValuedResourcesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_valued_resources(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.ListValuedResourcesRequest, dict]]): + The request object. Request message for listing the + valued resources for a given simulation. + parent (:class:`str`): + Required. Name of parent to list exposed resources. + + Valid formats: "organizations/{organization}", + "organizations/{organization}/simulations/{simulation}" + "organizations/{organization}/simulations/{simulation}/attackExposureResults/{attack_exposure_result_v2}" + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListValuedResourcesAsyncPager: + Response message for listing the + valued resources for a given simulation. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.ListValuedResourcesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_valued_resources, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListValuedResourcesAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def set_finding_state( + self, + request: Optional[ + Union[securitycenter_service.SetFindingStateRequest, dict] + ] = None, + *, + name: Optional[str] = None, + state: Optional[finding.Finding.State] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> finding.Finding: + r"""Updates the state of a finding. If no location is + specified, finding is assumed to be in global + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_set_finding_state(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.SetFindingStateRequest( + name="name_value", + state="INACTIVE", + ) + + # Make the request + response = await client.set_finding_state(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.SetFindingStateRequest, dict]]): + The request object. Request message for updating a + finding's state. + name (:class:`str`): + Required. The `relative resource + name `__ + of the finding. If no location is specified, finding is + assumed to be in global. The following list shows some + examples: + + - + + ``organizations/{organization_id}/sources/{source_id}/findings/{finding_id}`` + + + ``organizations/{organization_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``folders/{folder_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``folders/{folder_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``projects/{project_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``projects/{project_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + state (:class:`google.cloud.securitycenter_v2.types.Finding.State`): + Required. The desired State of the + finding. + + This corresponds to the ``state`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, state]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.SetFindingStateRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if state is not None: + request.state = state + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.set_finding_state, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def set_iam_policy( + self, + request: Optional[Union[iam_policy_pb2.SetIamPolicyRequest, dict]] = None, + *, + resource: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> policy_pb2.Policy: + r"""Sets the access control policy on the specified + Source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + from google.iam.v1 import iam_policy_pb2 # type: ignore + + async def sample_set_iam_policy(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = iam_policy_pb2.SetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = await client.set_iam_policy(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]]): + The request object. Request message for ``SetIamPolicy`` method. + resource (:class:`str`): + REQUIRED: The resource for which the + policy is being specified. See the + operation documentation for the + appropriate value for this field. + + This corresponds to the ``resource`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.iam.v1.policy_pb2.Policy: + An Identity and Access Management (IAM) policy, which specifies access + controls for Google Cloud resources. + + A Policy is a collection of bindings. A binding binds + one or more members, or principals, to a single role. + Principals can be user accounts, service accounts, + Google groups, and domains (such as G Suite). A role + is a named list of permissions; each role can be an + IAM predefined role or a user-created custom role. + + For some types of Google Cloud resources, a binding + can also specify a condition, which is a logical + expression that allows access to a resource only if + the expression evaluates to true. A condition can add + constraints based on attributes of the request, the + resource, or both. To learn which resources support + conditions in their IAM policies, see the [IAM + documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies). + + **JSON example:** + + :literal:`\` { "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')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \` + + **YAML example:** + + :literal:`\` 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') etag: BwWWja0YfJA= version: 3`\ \` + + For a description of IAM and its features, see the + [IAM + documentation](\ https://cloud.google.com/iam/docs/). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = iam_policy_pb2.SetIamPolicyRequest(**request) + elif not request: + request = iam_policy_pb2.SetIamPolicyRequest( + resource=resource, + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.set_iam_policy, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def set_mute( + self, + request: Optional[Union[securitycenter_service.SetMuteRequest, dict]] = None, + *, + name: Optional[str] = None, + mute: Optional[finding.Finding.Mute] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> finding.Finding: + r"""Updates the mute state of a finding. If no location + is specified, finding is assumed to be in global + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_set_mute(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.SetMuteRequest( + name="name_value", + mute="UNDEFINED", + ) + + # Make the request + response = await client.set_mute(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.SetMuteRequest, dict]]): + The request object. Request message for updating a + finding's mute status. + name (:class:`str`): + Required. The `relative resource + name `__ + of the finding. If no location is specified, finding is + assumed to be in global. The following list shows some + examples: + + - + + ``organizations/{organization_id}/sources/{source_id}/findings/{finding_id}`` + + + ``organizations/{organization_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``folders/{folder_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``folders/{folder_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``projects/{project_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``projects/{project_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mute (:class:`google.cloud.securitycenter_v2.types.Finding.Mute`): + Required. The desired state of the + Mute. + + This corresponds to the ``mute`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, mute]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.SetMuteRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if mute is not None: + request.mute = mute + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.set_mute, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def test_iam_permissions( + self, + request: Optional[Union[iam_policy_pb2.TestIamPermissionsRequest, dict]] = None, + *, + resource: Optional[str] = None, + permissions: Optional[MutableSequence[str]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> iam_policy_pb2.TestIamPermissionsResponse: + r"""Returns the permissions that a caller has on the + specified source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + from google.iam.v1 import iam_policy_pb2 # type: ignore + + async def sample_test_iam_permissions(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = iam_policy_pb2.TestIamPermissionsRequest( + resource="resource_value", + permissions=['permissions_value1', 'permissions_value2'], + ) + + # Make the request + response = await client.test_iam_permissions(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]]): + The request object. Request message for ``TestIamPermissions`` method. + resource (:class:`str`): + REQUIRED: The resource for which the + policy detail is being requested. See + the operation documentation for the + appropriate value for this field. + + This corresponds to the ``resource`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + permissions (:class:`MutableSequence[str]`): + The set of permissions to check for the ``resource``. + Permissions with wildcards (such as '*' or 'storage.*') + are not allowed. For more information see `IAM + Overview `__. + + This corresponds to the ``permissions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse: + Response message for TestIamPermissions method. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource, permissions]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = iam_policy_pb2.TestIamPermissionsRequest(**request) + elif not request: + request = iam_policy_pb2.TestIamPermissionsRequest( + resource=resource, + permissions=permissions, + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.test_iam_permissions, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_big_query_export( + self, + request: Optional[ + Union[securitycenter_service.UpdateBigQueryExportRequest, dict] + ] = None, + *, + big_query_export: Optional[bigquery_export.BigQueryExport] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bigquery_export.BigQueryExport: + r"""Updates a BigQuery export. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_update_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateBigQueryExportRequest( + ) + + # Make the request + response = await client.update_big_query_export(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.UpdateBigQueryExportRequest, dict]]): + The request object. Request message for updating a + BigQuery export. + big_query_export (:class:`google.cloud.securitycenter_v2.types.BigQueryExport`): + Required. The BigQuery export being + updated. + + This corresponds to the ``big_query_export`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The list of fields to be updated. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.BigQueryExport: + Configures how to deliver Findings to + BigQuery Instance. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([big_query_export, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.UpdateBigQueryExportRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if big_query_export is not None: + request.big_query_export = big_query_export + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_big_query_export, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("big_query_export.name", request.big_query_export.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_external_system( + self, + request: Optional[ + Union[securitycenter_service.UpdateExternalSystemRequest, dict] + ] = None, + *, + external_system: Optional[gcs_external_system.ExternalSystem] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_external_system.ExternalSystem: + r"""Updates external system. This is for a given finding. + If no location is specified, finding is assumed to be in + global + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_update_external_system(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateExternalSystemRequest( + ) + + # Make the request + response = await client.update_external_system(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.UpdateExternalSystemRequest, dict]]): + The request object. Request message for updating a + ExternalSystem resource. + external_system (:class:`google.cloud.securitycenter_v2.types.ExternalSystem`): + Required. The external system + resource to update. + + This corresponds to the ``external_system`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The FieldMask to use when updating + the external system resource. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.ExternalSystem: + Representation of third party + SIEM/SOAR fields within SCC. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([external_system, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.UpdateExternalSystemRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if external_system is not None: + request.external_system = external_system + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_external_system, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("external_system.name", request.external_system.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_finding( + self, + request: Optional[ + Union[securitycenter_service.UpdateFindingRequest, dict] + ] = None, + *, + finding: Optional[gcs_finding.Finding] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_finding.Finding: + r"""Creates or updates a finding. If no location is + specified, finding is assumed to be in global. The + corresponding source must exist for a finding creation + to succeed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_update_finding(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateFindingRequest( + ) + + # Make the request + response = await client.update_finding(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.UpdateFindingRequest, dict]]): + The request object. Request message for updating or + creating a finding. + finding (:class:`google.cloud.securitycenter_v2.types.Finding`): + Required. The finding resource to update or create if it + does not already exist. parent, security_marks, and + update_time will be ignored. + + In the case of creation, the finding id portion of the + name must be alphanumeric and less than or equal to 32 + characters and greater than 0 characters in length. + + This corresponds to the ``finding`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The FieldMask to use when updating the finding resource. + This field should not be specified when creating a + finding. + + When updating a finding, an empty mask is treated as + updating all mutable fields and replacing + source_properties. Individual source_properties can be + added/updated by using "source_properties." in the field + mask. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([finding, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.UpdateFindingRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if finding is not None: + request.finding = finding + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_finding, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("finding.name", request.finding.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_mute_config( + self, + request: Optional[ + Union[securitycenter_service.UpdateMuteConfigRequest, dict] + ] = None, + *, + mute_config: Optional[gcs_mute_config.MuteConfig] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_mute_config.MuteConfig: + r"""Updates a mute config. If no location is specified, + default is global. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_update_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + mute_config = securitycenter_v2.MuteConfig() + mute_config.filter = "filter_value" + mute_config.type_ = "STATIC" + + request = securitycenter_v2.UpdateMuteConfigRequest( + mute_config=mute_config, + ) + + # Make the request + response = await client.update_mute_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.UpdateMuteConfigRequest, dict]]): + The request object. Request message for updating a mute + config. + mute_config (:class:`google.cloud.securitycenter_v2.types.MuteConfig`): + Required. The mute config being + updated. + + This corresponds to the ``mute_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The list of fields to be updated. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.MuteConfig: + A mute config is a Cloud SCC resource + that contains the configuration to mute + create/update events of findings. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([mute_config, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.UpdateMuteConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if mute_config is not None: + request.mute_config = mute_config + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_mute_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("mute_config.name", request.mute_config.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_notification_config( + self, + request: Optional[ + Union[securitycenter_service.UpdateNotificationConfigRequest, dict] + ] = None, + *, + notification_config: Optional[ + gcs_notification_config.NotificationConfig + ] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_notification_config.NotificationConfig: + r"""Updates a notification config. The following update fields are + allowed: description, pubsub_topic, streaming_config.filter + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_update_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateNotificationConfigRequest( + ) + + # Make the request + response = await client.update_notification_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.UpdateNotificationConfigRequest, dict]]): + The request object. Request message for updating a + notification config. + notification_config (:class:`google.cloud.securitycenter_v2.types.NotificationConfig`): + Required. The notification config to + update. + + This corresponds to the ``notification_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The FieldMask to use when updating + the notification config. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.NotificationConfig: + Cloud Security Command Center (Cloud + SCC) notification configs. + A notification config is a Cloud SCC + resource that contains the configuration + to send notifications for create/update + events of findings, assets and etc. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([notification_config, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.UpdateNotificationConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if notification_config is not None: + request.notification_config = notification_config + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_notification_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("notification_config.name", request.notification_config.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_resource_value_config( + self, + request: Optional[ + Union[securitycenter_service.UpdateResourceValueConfigRequest, dict] + ] = None, + *, + resource_value_config: Optional[ + gcs_resource_value_config.ResourceValueConfig + ] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_resource_value_config.ResourceValueConfig: + r"""Updates an existing ResourceValueConfigs with new + rules. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_update_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + resource_value_config = securitycenter_v2.ResourceValueConfig() + resource_value_config.tag_values = ['tag_values_value1', 'tag_values_value2'] + + request = securitycenter_v2.UpdateResourceValueConfigRequest( + resource_value_config=resource_value_config, + ) + + # Make the request + response = await client.update_resource_value_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.UpdateResourceValueConfigRequest, dict]]): + The request object. Request message to update resource + value config + resource_value_config (:class:`google.cloud.securitycenter_v2.types.ResourceValueConfig`): + Required. The resource value config + being updated. + + This corresponds to the ``resource_value_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The list of fields to be updated. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.ResourceValueConfig: + A resource value config (RVC) is a + mapping configuration of user's + resources to resource values. Used in + Attack path simulations. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_value_config, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.UpdateResourceValueConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_value_config is not None: + request.resource_value_config = resource_value_config + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_resource_value_config, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_value_config.name", request.resource_value_config.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_security_marks( + self, + request: Optional[ + Union[securitycenter_service.UpdateSecurityMarksRequest, dict] + ] = None, + *, + security_marks: Optional[gcs_security_marks.SecurityMarks] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_security_marks.SecurityMarks: + r"""Updates security marks. For Finding Security marks, + if no location is specified, finding is assumed to be in + global. Assets Security Marks can only be accessed + through global endpoint. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_update_security_marks(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateSecurityMarksRequest( + ) + + # Make the request + response = await client.update_security_marks(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.UpdateSecurityMarksRequest, dict]]): + The request object. Request message for updating a + SecurityMarks resource. + security_marks (:class:`google.cloud.securitycenter_v2.types.SecurityMarks`): + Required. The security marks resource + to update. + + This corresponds to the ``security_marks`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The FieldMask to use when updating the security marks + resource. + + The field mask must not contain duplicate fields. If + empty or set to "marks", all marks will be replaced. + Individual marks can be updated using + "marks.". + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.SecurityMarks: + User specified security marks that + are attached to the parent Security + Command Center resource. Security marks + are scoped within a Security Command + Center organization -- they can be + modified and viewed by all users who + have proper permissions on the + organization. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([security_marks, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.UpdateSecurityMarksRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if security_marks is not None: + request.security_marks = security_marks + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_security_marks, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("security_marks.name", request.security_marks.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_source( + self, + request: Optional[ + Union[securitycenter_service.UpdateSourceRequest, dict] + ] = None, + *, + source: Optional[gcs_source.Source] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_source.Source: + r"""Updates a source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + async def sample_update_source(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateSourceRequest( + ) + + # Make the request + response = await client.update_source(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.securitycenter_v2.types.UpdateSourceRequest, dict]]): + The request object. Request message for updating a + source. + source (:class:`google.cloud.securitycenter_v2.types.Source`): + Required. The source resource to + update. + + This corresponds to the ``source`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The FieldMask to use when updating + the source resource. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Source: + Security Command Center finding + source. A finding source is an entity or + a mechanism that can produce a finding. + A source is like a container of findings + that come from the same scanner, logger, + monitor, and other tools. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([source, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = securitycenter_service.UpdateSourceRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if source is not None: + request.source = source + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_source, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("source.name", request.source.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` 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): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # 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): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_operation( + self, + request: Optional[operations_pb2.DeleteOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a long-running operation. + + This method indicates that the client is no longer interested + in the operation result. It does not cancel the operation. + If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # 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): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # 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): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.cancel_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def __aenter__(self) -> "SecurityCenterAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +__all__ = ("SecurityCenterAsyncClient",) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/client.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/client.py new file mode 100644 index 000000000000..7b971f7c919e --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/client.py @@ -0,0 +1,6467 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from collections import OrderedDict +import os +import re +from typing import ( + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.securitycenter_v2 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.iam.v1 import iam_policy_pb2 # type: ignore +from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.securitycenter_v2.services.security_center import pagers +from google.cloud.securitycenter_v2.types import ( + access, + application, + attack_exposure, + attack_path, + backup_disaster_recovery, + bigquery_export, + cloud_dlp_data_profile, + cloud_dlp_inspection, + compliance, + connection, + container, + database, + exfiltration, +) +from google.cloud.securitycenter_v2.types import ( + iam_binding, + indicator, + kernel_rootkit, + kubernetes, + load_balancer, + log_entry, + mitre_attack, +) +from google.cloud.securitycenter_v2.types import ( + security_posture, + securitycenter_service, + simulation, +) +from google.cloud.securitycenter_v2.types import external_system as gcs_external_system +from google.cloud.securitycenter_v2.types import ( + notification_config as gcs_notification_config, +) +from google.cloud.securitycenter_v2.types import ( + resource_value_config as gcs_resource_value_config, +) +from google.cloud.securitycenter_v2.types import security_marks as gcs_security_marks +from google.cloud.securitycenter_v2.types import file +from google.cloud.securitycenter_v2.types import finding +from google.cloud.securitycenter_v2.types import finding as gcs_finding +from google.cloud.securitycenter_v2.types import mute_config +from google.cloud.securitycenter_v2.types import mute_config as gcs_mute_config +from google.cloud.securitycenter_v2.types import notification_config +from google.cloud.securitycenter_v2.types import org_policy, process +from google.cloud.securitycenter_v2.types import resource_value_config +from google.cloud.securitycenter_v2.types import security_marks +from google.cloud.securitycenter_v2.types import source +from google.cloud.securitycenter_v2.types import source as gcs_source +from google.cloud.securitycenter_v2.types import valued_resource, vulnerability + +from .transports.base import DEFAULT_CLIENT_INFO, SecurityCenterTransport +from .transports.grpc import SecurityCenterGrpcTransport +from .transports.grpc_asyncio import SecurityCenterGrpcAsyncIOTransport +from .transports.rest import SecurityCenterRestTransport + + +class SecurityCenterClientMeta(type): + """Metaclass for the SecurityCenter client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[SecurityCenterTransport]] + _transport_registry["grpc"] = SecurityCenterGrpcTransport + _transport_registry["grpc_asyncio"] = SecurityCenterGrpcAsyncIOTransport + _transport_registry["rest"] = SecurityCenterRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[SecurityCenterTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class SecurityCenterClient(metaclass=SecurityCenterClientMeta): + """V2 APIs for Security Center service.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "securitycenter.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "securitycenter.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @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: + SecurityCenterClient: 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 + 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: + SecurityCenterClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SecurityCenterTransport: + """Returns the transport used by the client instance. + + Returns: + SecurityCenterTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def attack_path_path( + organization: str, + simulation: str, + valued_resource: str, + attack_path: str, + ) -> str: + """Returns a fully-qualified attack_path string.""" + return "organizations/{organization}/simulations/{simulation}/valuedResources/{valued_resource}/attackPaths/{attack_path}".format( + organization=organization, + simulation=simulation, + valued_resource=valued_resource, + attack_path=attack_path, + ) + + @staticmethod + def parse_attack_path_path(path: str) -> Dict[str, str]: + """Parses a attack_path path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/simulations/(?P.+?)/valuedResources/(?P.+?)/attackPaths/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def big_query_export_path( + organization: str, + location: str, + export: str, + ) -> str: + """Returns a fully-qualified big_query_export string.""" + return "organizations/{organization}/locations/{location}/bigQueryExports/{export}".format( + organization=organization, + location=location, + export=export, + ) + + @staticmethod + def parse_big_query_export_path(path: str) -> Dict[str, str]: + """Parses a big_query_export path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/locations/(?P.+?)/bigQueryExports/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def dlp_job_path( + project: str, + dlp_job: str, + ) -> str: + """Returns a fully-qualified dlp_job string.""" + return "projects/{project}/dlpJobs/{dlp_job}".format( + project=project, + dlp_job=dlp_job, + ) + + @staticmethod + def parse_dlp_job_path(path: str) -> Dict[str, str]: + """Parses a dlp_job path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/dlpJobs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def external_system_path( + organization: str, + source: str, + finding: str, + externalsystem: str, + ) -> str: + """Returns a fully-qualified external_system string.""" + return "organizations/{organization}/sources/{source}/findings/{finding}/externalSystems/{externalsystem}".format( + organization=organization, + source=source, + finding=finding, + externalsystem=externalsystem, + ) + + @staticmethod + def parse_external_system_path(path: str) -> Dict[str, str]: + """Parses a external_system path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/sources/(?P.+?)/findings/(?P.+?)/externalSystems/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def finding_path( + organization: str, + source: str, + finding: str, + ) -> str: + """Returns a fully-qualified finding string.""" + return ( + "organizations/{organization}/sources/{source}/findings/{finding}".format( + organization=organization, + source=source, + finding=finding, + ) + ) + + @staticmethod + def parse_finding_path(path: str) -> Dict[str, str]: + """Parses a finding path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/sources/(?P.+?)/findings/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mute_config_path( + organization: str, + mute_config: str, + ) -> str: + """Returns a fully-qualified mute_config string.""" + return "organizations/{organization}/muteConfigs/{mute_config}".format( + organization=organization, + mute_config=mute_config, + ) + + @staticmethod + def parse_mute_config_path(path: str) -> Dict[str, str]: + """Parses a mute_config path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/muteConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def notification_config_path( + organization: str, + location: str, + notification_config: str, + ) -> str: + """Returns a fully-qualified notification_config string.""" + return "organizations/{organization}/locations/{location}/notificationConfigs/{notification_config}".format( + organization=organization, + location=location, + notification_config=notification_config, + ) + + @staticmethod + def parse_notification_config_path(path: str) -> Dict[str, str]: + """Parses a notification_config path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/locations/(?P.+?)/notificationConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def policy_path( + organization: str, + constraint_name: str, + ) -> str: + """Returns a fully-qualified policy string.""" + return "organizations/{organization}/policies/{constraint_name}".format( + organization=organization, + constraint_name=constraint_name, + ) + + @staticmethod + def parse_policy_path(path: str) -> Dict[str, str]: + """Parses a policy path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/policies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def resource_value_config_path( + organization: str, + resource_value_config: str, + ) -> str: + """Returns a fully-qualified resource_value_config string.""" + return "organizations/{organization}/resourceValueConfigs/{resource_value_config}".format( + organization=organization, + resource_value_config=resource_value_config, + ) + + @staticmethod + def parse_resource_value_config_path(path: str) -> Dict[str, str]: + """Parses a resource_value_config path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/resourceValueConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def security_marks_path( + organization: str, + asset: str, + ) -> str: + """Returns a fully-qualified security_marks string.""" + return "organizations/{organization}/assets/{asset}/securityMarks".format( + organization=organization, + asset=asset, + ) + + @staticmethod + def parse_security_marks_path(path: str) -> Dict[str, str]: + """Parses a security_marks path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/assets/(?P.+?)/securityMarks$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def simulation_path( + organization: str, + simulation: str, + ) -> str: + """Returns a fully-qualified simulation string.""" + return "organizations/{organization}/simulations/{simulation}".format( + organization=organization, + simulation=simulation, + ) + + @staticmethod + def parse_simulation_path(path: str) -> Dict[str, str]: + """Parses a simulation path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/simulations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def source_path( + organization: str, + source: str, + ) -> str: + """Returns a fully-qualified source string.""" + return "organizations/{organization}/sources/{source}".format( + organization=organization, + source=source, + ) + + @staticmethod + def parse_source_path(path: str) -> Dict[str, str]: + """Parses a source path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/sources/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def table_data_profile_path( + project: str, + table_profile: str, + ) -> str: + """Returns a fully-qualified table_data_profile string.""" + return "projects/{project}/tableProfiles/{table_profile}".format( + project=project, + table_profile=table_profile, + ) + + @staticmethod + def parse_table_data_profile_path(path: str) -> Dict[str, str]: + """Parses a table_data_profile path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/tableProfiles/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def topic_path( + project: str, + topic: str, + ) -> str: + """Returns a fully-qualified topic string.""" + return "projects/{project}/topics/{topic}".format( + project=project, + topic=topic, + ) + + @staticmethod + def parse_topic_path(path: str) -> Dict[str, str]: + """Parses a topic path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/topics/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def valued_resource_path( + organization: str, + simulation: str, + valued_resource: str, + ) -> str: + """Returns a fully-qualified valued_resource string.""" + return "organizations/{organization}/simulations/{simulation}/valuedResources/{valued_resource}".format( + organization=organization, + simulation=simulation, + valued_resource=valued_resource, + ) + + @staticmethod + def parse_valued_resource_path(path: str) -> Dict[str, str]: + """Parses a valued_resource path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/simulations/(?P.+?)/valuedResources/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = SecurityCenterClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = SecurityCenterClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = SecurityCenterClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = SecurityCenterClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + @staticmethod + def _compare_universes( + client_universe: str, credentials: ga_credentials.Credentials + ) -> bool: + """Returns True iff the universe domains used by the client and credentials match. + + Args: + client_universe (str): The universe domain configured via the client options. + credentials (ga_credentials.Credentials): The credentials being used in the client. + + Returns: + bool: True iff client_universe matches the universe in credentials. + + Raises: + ValueError: when client_universe does not match the universe in credentials. + """ + + default_universe = SecurityCenterClient._DEFAULT_UNIVERSE + credentials_universe = getattr(credentials, "universe_domain", default_universe) + + if client_universe != credentials_universe: + raise ValueError( + "The configured universe domain " + f"({client_universe}) does not match the universe domain " + f"found in the credentials ({credentials_universe}). " + "If you haven't configured the universe domain explicitly, " + f"`{default_universe}` is the default." + ) + return True + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + self._is_universe_domain_valid = ( + self._is_universe_domain_valid + or SecurityCenterClient._compare_universes( + self.universe_domain, self.transport._credentials + ) + ) + return self._is_universe_domain_valid + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, SecurityCenterTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the security center client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + 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, SecurityCenterTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = SecurityCenterClient._read_environment_variables() + self._client_cert_source = SecurityCenterClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = SecurityCenterClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + api_key_value = getattr(self._client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, SecurityCenterTransport) + if transport_provided: + # transport is a SecurityCenterTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(SecurityCenterTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or SecurityCenterClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + Transport = type(self).get_transport_class(cast(str, transport)) + self._transport = Transport( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + def batch_create_resource_value_configs( + self, + request: Optional[ + Union[securitycenter_service.BatchCreateResourceValueConfigsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + requests: Optional[ + MutableSequence[securitycenter_service.CreateResourceValueConfigRequest] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.BatchCreateResourceValueConfigsResponse: + r"""Creates a ResourceValueConfig for an organization. + Maps user's tags to difference resource values for use + by the attack path simulation. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_batch_create_resource_value_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + requests = securitycenter_v2.CreateResourceValueConfigRequest() + requests.parent = "parent_value" + requests.resource_value_config.tag_values = ['tag_values_value1', 'tag_values_value2'] + + request = securitycenter_v2.BatchCreateResourceValueConfigsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_resource_value_configs(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.BatchCreateResourceValueConfigsRequest, dict]): + The request object. Request message to create multiple + resource value configs + parent (str): + Required. Resource name of the new + ResourceValueConfig's parent. The parent + field in the + CreateResourceValueConfigRequest + messages must either be empty or match + this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.cloud.securitycenter_v2.types.CreateResourceValueConfigRequest]): + Required. The resource value configs + to be created. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.BatchCreateResourceValueConfigsResponse: + Response message for + BatchCreateResourceValueConfigs + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, requests]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.BatchCreateResourceValueConfigsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, securitycenter_service.BatchCreateResourceValueConfigsRequest + ): + request = securitycenter_service.BatchCreateResourceValueConfigsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_create_resource_value_configs + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def bulk_mute_findings( + self, + request: Optional[ + Union[securitycenter_service.BulkMuteFindingsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Kicks off an LRO to bulk mute findings for a parent + based on a filter. If no location is specified, findings + are muted in global. The parent can be either an + organization, folder, or project. The findings matched + by the filter will be muted after the LRO is done. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_bulk_mute_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.BulkMuteFindingsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.bulk_mute_findings(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.BulkMuteFindingsRequest, dict]): + The request object. Request message for bulk findings + update. + Note: + + 1. If multiple bulk update requests + match the same resource, the order + in which they get executed is not + defined. + 2. Once a bulk operation is started, + there is no way to stop it. + parent (str): + Required. The parent, at which bulk action needs to be + applied. If no location is specified, findings are + updated in global. The following list shows some + examples: + + - ``organizations/[organization_id]`` + - ``organizations/[organization_id]/locations/[location_id]`` + - ``folders/[folder_id]`` + - ``folders/[folder_id]/locations/[location_id]`` + - ``projects/[project_id]`` + - ``projects/[project_id]/locations/[location_id]`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.securitycenter_v2.types.BulkMuteFindingsResponse` + The response to a BulkMute request. Contains the LRO + information. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.BulkMuteFindingsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.BulkMuteFindingsRequest): + request = securitycenter_service.BulkMuteFindingsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.bulk_mute_findings] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + securitycenter_service.BulkMuteFindingsResponse, + metadata_type=empty_pb2.Empty, + ) + + # Done; return the response. + return response + + def create_big_query_export( + self, + request: Optional[ + Union[securitycenter_service.CreateBigQueryExportRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + big_query_export: Optional[bigquery_export.BigQueryExport] = None, + big_query_export_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bigquery_export.BigQueryExport: + r"""Creates a BigQuery export. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_create_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateBigQueryExportRequest( + parent="parent_value", + big_query_export_id="big_query_export_id_value", + ) + + # Make the request + response = client.create_big_query_export(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.CreateBigQueryExportRequest, dict]): + The request object. Request message for creating a + BigQuery export. + parent (str): + Required. The name of the parent resource of the new + BigQuery export. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + big_query_export (google.cloud.securitycenter_v2.types.BigQueryExport): + Required. The BigQuery export being + created. + + This corresponds to the ``big_query_export`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + big_query_export_id (str): + Required. Unique identifier provided + by the client within the parent scope. + It must consist of only lowercase + letters, numbers, and hyphens, must + start with a letter, must end with + either a letter or a number, and must be + 63 characters or less. + + This corresponds to the ``big_query_export_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.BigQueryExport: + Configures how to deliver Findings to + BigQuery Instance. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, big_query_export, big_query_export_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.CreateBigQueryExportRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.CreateBigQueryExportRequest): + request = securitycenter_service.CreateBigQueryExportRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if big_query_export is not None: + request.big_query_export = big_query_export + if big_query_export_id is not None: + request.big_query_export_id = big_query_export_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_big_query_export] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_finding( + self, + request: Optional[ + Union[securitycenter_service.CreateFindingRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + finding: Optional[gcs_finding.Finding] = None, + finding_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_finding.Finding: + r"""Creates a finding in a location. The corresponding + source must exist for finding creation to succeed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_create_finding(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateFindingRequest( + parent="parent_value", + finding_id="finding_id_value", + ) + + # Make the request + response = client.create_finding(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.CreateFindingRequest, dict]): + The request object. Request message for creating a + finding. + parent (str): + Required. Resource name of the new finding's parent. The + following list shows some examples of the format: + + ``organizations/[organization_id]/sources/[source_id]`` + + + ``organizations/[organization_id]/sources/[source_id]/locations/[location_id]`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + finding (google.cloud.securitycenter_v2.types.Finding): + Required. The Finding being created. The name and + security_marks will be ignored as they are both output + only fields on this resource. + + This corresponds to the ``finding`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + finding_id (str): + Required. Unique identifier provided + by the client within the parent scope. + It must be alphanumeric and less than or + equal to 32 characters and greater than + 0 characters in length. + + This corresponds to the ``finding_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, finding, finding_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.CreateFindingRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.CreateFindingRequest): + request = securitycenter_service.CreateFindingRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if finding is not None: + request.finding = finding + if finding_id is not None: + request.finding_id = finding_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_finding] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_mute_config( + self, + request: Optional[ + Union[securitycenter_service.CreateMuteConfigRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + mute_config: Optional[gcs_mute_config.MuteConfig] = None, + mute_config_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_mute_config.MuteConfig: + r"""Creates a mute config. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_create_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + mute_config = securitycenter_v2.MuteConfig() + mute_config.filter = "filter_value" + mute_config.type_ = "STATIC" + + request = securitycenter_v2.CreateMuteConfigRequest( + parent="parent_value", + mute_config=mute_config, + mute_config_id="mute_config_id_value", + ) + + # Make the request + response = client.create_mute_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.CreateMuteConfigRequest, dict]): + The request object. Request message for creating a mute + config. + parent (str): + Required. Resource name of the new mute configs's + parent. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mute_config (google.cloud.securitycenter_v2.types.MuteConfig): + Required. The mute config being + created. + + This corresponds to the ``mute_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mute_config_id (str): + Required. Unique identifier provided + by the client within the parent scope. + It must consist of only lowercase + letters, numbers, and hyphens, must + start with a letter, must end with + either a letter or a number, and must be + 63 characters or less. + + This corresponds to the ``mute_config_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.MuteConfig: + A mute config is a Cloud SCC resource + that contains the configuration to mute + create/update events of findings. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, mute_config, mute_config_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.CreateMuteConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.CreateMuteConfigRequest): + request = securitycenter_service.CreateMuteConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if mute_config is not None: + request.mute_config = mute_config + if mute_config_id is not None: + request.mute_config_id = mute_config_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_mute_config] + + header_params = {} + + routing_param_regex = re.compile( + "^projects/[^/]+/locations/(?P[^/]+)$" + ) + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + routing_param_regex = re.compile( + "^organizations/[^/]+/locations/(?P[^/]+)$" + ) + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + routing_param_regex = re.compile( + "^folders/[^/]+/locations/(?P[^/]+)$" + ) + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_notification_config( + self, + request: Optional[ + Union[securitycenter_service.CreateNotificationConfigRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + notification_config: Optional[ + gcs_notification_config.NotificationConfig + ] = None, + config_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_notification_config.NotificationConfig: + r"""Creates a notification config. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_create_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateNotificationConfigRequest( + parent="parent_value", + config_id="config_id_value", + ) + + # Make the request + response = client.create_notification_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.CreateNotificationConfigRequest, dict]): + The request object. Request message for creating a + notification config. + parent (str): + Required. Resource name of the new notification config's + parent. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + notification_config (google.cloud.securitycenter_v2.types.NotificationConfig): + Required. The notification config + being created. The name and the service + account will be ignored as they are both + output only fields on this resource. + + This corresponds to the ``notification_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + config_id (str): + Required. + Unique identifier provided by the client + within the parent scope. It must be + between 1 and 128 characters and contain + alphanumeric characters, underscores, or + hyphens only. + + This corresponds to the ``config_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.NotificationConfig: + Cloud Security Command Center (Cloud + SCC) notification configs. + A notification config is a Cloud SCC + resource that contains the configuration + to send notifications for create/update + events of findings, assets and etc. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, notification_config, config_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.CreateNotificationConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, securitycenter_service.CreateNotificationConfigRequest + ): + request = securitycenter_service.CreateNotificationConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if notification_config is not None: + request.notification_config = notification_config + if config_id is not None: + request.config_id = config_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_notification_config + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_source( + self, + request: Optional[ + Union[securitycenter_service.CreateSourceRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + source: Optional[gcs_source.Source] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_source.Source: + r"""Creates a source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_create_source(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateSourceRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_source(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.CreateSourceRequest, dict]): + The request object. Request message for creating a + source. + parent (str): + Required. Resource name of the new source's parent. Its + format should be "organizations/[organization_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + source (google.cloud.securitycenter_v2.types.Source): + Required. The Source being created, only the + display_name and description will be used. All other + fields will be ignored. + + This corresponds to the ``source`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Source: + Security Command Center finding + source. A finding source is an entity or + a mechanism that can produce a finding. + A source is like a container of findings + that come from the same scanner, logger, + monitor, and other tools. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, source]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.CreateSourceRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.CreateSourceRequest): + request = securitycenter_service.CreateSourceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if source is not None: + request.source = source + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_source] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_big_query_export( + self, + request: Optional[ + Union[securitycenter_service.DeleteBigQueryExportRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes an existing BigQuery export. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_delete_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteBigQueryExportRequest( + name="name_value", + ) + + # Make the request + client.delete_big_query_export(request=request) + + Args: + request (Union[google.cloud.securitycenter_v2.types.DeleteBigQueryExportRequest, dict]): + The request object. Request message for deleting a + BigQuery export. + name (str): + Required. The name of the BigQuery export to delete. The + following list shows some examples of the format: + + - + + ``organizations/{organization}/locations/{location}/bigQueryExports/{export_id}`` + + - ``folders/{folder}/locations/{location}/bigQueryExports/{export_id}`` + - ``projects/{project}/locations/{location}/bigQueryExports/{export_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.DeleteBigQueryExportRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.DeleteBigQueryExportRequest): + request = securitycenter_service.DeleteBigQueryExportRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_big_query_export] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def delete_mute_config( + self, + request: Optional[ + Union[securitycenter_service.DeleteMuteConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes an existing mute config. If no location is + specified, default is global. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_delete_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteMuteConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_mute_config(request=request) + + Args: + request (Union[google.cloud.securitycenter_v2.types.DeleteMuteConfigRequest, dict]): + The request object. Request message for deleting a mute + config. If no location is specified, + default is global. + name (str): + Required. Name of the mute config to delete. The + following list shows some examples of the format: + + - ``organizations/{organization}/muteConfigs/{config_id}`` + - + + ``organizations/{organization}/locations/{location}/muteConfigs/{config_id}`` + + - ``folders/{folder}/muteConfigs/{config_id}`` + - ``folders/{folder}/locations/{location}/muteConfigs/{config_id}`` + - ``projects/{project}/muteConfigs/{config_id}`` + - ``projects/{project}/locations/{location}/muteConfigs/{config_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.DeleteMuteConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.DeleteMuteConfigRequest): + request = securitycenter_service.DeleteMuteConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_mute_config] + + header_params = {} + + routing_param_regex = re.compile( + "^projects/[^/]+/locations/(?P[^/]+)/muteConfigs/[^/]+$" + ) + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + routing_param_regex = re.compile( + "^organizations/[^/]+/locations/(?P[^/]+)/muteConfigs/[^/]+$" + ) + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + routing_param_regex = re.compile( + "^folders/[^/]+/locations/(?P[^/]+)/muteConfigs/[^/]+$" + ) + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def delete_notification_config( + self, + request: Optional[ + Union[securitycenter_service.DeleteNotificationConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a notification config. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_delete_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteNotificationConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_notification_config(request=request) + + Args: + request (Union[google.cloud.securitycenter_v2.types.DeleteNotificationConfigRequest, dict]): + The request object. Request message for deleting a + notification config. + name (str): + Required. Name of the notification config to delete. The + following list shows some examples of the format: + + - + + ``organizations/[organization_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + + ``folders/[folder_id]/locations/[location_id]notificationConfigs/[config_id]`` + + + ``projects/[project_id]/locations/[location_id]notificationConfigs/[config_id]`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.DeleteNotificationConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, securitycenter_service.DeleteNotificationConfigRequest + ): + request = securitycenter_service.DeleteNotificationConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.delete_notification_config + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def delete_resource_value_config( + self, + request: Optional[ + Union[securitycenter_service.DeleteResourceValueConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a ResourceValueConfig. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_delete_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteResourceValueConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_resource_value_config(request=request) + + Args: + request (Union[google.cloud.securitycenter_v2.types.DeleteResourceValueConfigRequest, dict]): + The request object. Request message to delete resource + value config + name (str): + Required. Name of the + ResourceValueConfig to delete + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.DeleteResourceValueConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, securitycenter_service.DeleteResourceValueConfigRequest + ): + request = securitycenter_service.DeleteResourceValueConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.delete_resource_value_config + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_big_query_export( + self, + request: Optional[ + Union[securitycenter_service.GetBigQueryExportRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bigquery_export.BigQueryExport: + r"""Gets a BigQuery export. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_get_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetBigQueryExportRequest( + name="name_value", + ) + + # Make the request + response = client.get_big_query_export(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.GetBigQueryExportRequest, dict]): + The request object. Request message for retrieving a + BigQuery export. + name (str): + Required. Name of the BigQuery export to retrieve. The + following list shows some examples of the format: + + - + + ``organizations/{organization}/locations/{location}/bigQueryExports/{export_id}`` + + - ``folders/{folder}/locations/{location}/bigQueryExports/{export_id}`` + - ``projects/{project}locations/{location}//bigQueryExports/{export_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.BigQueryExport: + Configures how to deliver Findings to + BigQuery Instance. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.GetBigQueryExportRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.GetBigQueryExportRequest): + request = securitycenter_service.GetBigQueryExportRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_big_query_export] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_simulation( + self, + request: Optional[ + Union[securitycenter_service.GetSimulationRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> simulation.Simulation: + r"""Get the simulation by name or the latest simulation + for the given organization. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_get_simulation(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetSimulationRequest( + name="name_value", + ) + + # Make the request + response = client.get_simulation(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.GetSimulationRequest, dict]): + The request object. Request message for getting + simulation. Simulation name can include + "latest" to retrieve the latest + simulation For example, + "organizations/123/simulations/latest". + name (str): + Required. The organization name or + simulation name of this simulation + Valid format: + + "organizations/{organization}/simulations/latest" + "organizations/{organization}/simulations/{simulation}" + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Simulation: + Attack path simulation + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.GetSimulationRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.GetSimulationRequest): + request = securitycenter_service.GetSimulationRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_simulation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_valued_resource( + self, + request: Optional[ + Union[securitycenter_service.GetValuedResourceRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> valued_resource.ValuedResource: + r"""Get the valued resource by name + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_get_valued_resource(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetValuedResourceRequest( + name="name_value", + ) + + # Make the request + response = client.get_valued_resource(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.GetValuedResourceRequest, dict]): + The request object. Request message for getting a valued + resource. + name (str): + Required. The name of this valued resource + + Valid format: + "organizations/{organization}/simulations/{simulation}/valuedResources/{valued_resource}" + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.ValuedResource: + A resource that is determined to have + value to a user's system + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.GetValuedResourceRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.GetValuedResourceRequest): + request = securitycenter_service.GetValuedResourceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_valued_resource] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_iam_policy( + self, + request: Optional[Union[iam_policy_pb2.GetIamPolicyRequest, dict]] = None, + *, + resource: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> policy_pb2.Policy: + r"""Gets the access control policy on the specified + Source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + from google.iam.v1 import iam_policy_pb2 # type: ignore + + def sample_get_iam_policy(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = iam_policy_pb2.GetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = client.get_iam_policy(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]): + The request object. Request message for ``GetIamPolicy`` method. + resource (str): + REQUIRED: The resource for which the + policy is being requested. See the + operation documentation for the + appropriate value for this field. + + This corresponds to the ``resource`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.iam.v1.policy_pb2.Policy: + An Identity and Access Management (IAM) policy, which specifies access + controls for Google Cloud resources. + + A Policy is a collection of bindings. A binding binds + one or more members, or principals, to a single role. + Principals can be user accounts, service accounts, + Google groups, and domains (such as G Suite). A role + is a named list of permissions; each role can be an + IAM predefined role or a user-created custom role. + + For some types of Google Cloud resources, a binding + can also specify a condition, which is a logical + expression that allows access to a resource only if + the expression evaluates to true. A condition can add + constraints based on attributes of the request, the + resource, or both. To learn which resources support + conditions in their IAM policies, see the [IAM + documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies). + + **JSON example:** + + :literal:`\` { "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')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \` + + **YAML example:** + + :literal:`\` 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') etag: BwWWja0YfJA= version: 3`\ \` + + For a description of IAM and its features, see the + [IAM + documentation](\ https://cloud.google.com/iam/docs/). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + if isinstance(request, dict): + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + request = iam_policy_pb2.GetIamPolicyRequest(**request) + elif not request: + # Null request, just make one. + request = iam_policy_pb2.GetIamPolicyRequest() + if resource is not None: + request.resource = resource + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_iam_policy] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_mute_config( + self, + request: Optional[ + Union[securitycenter_service.GetMuteConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> mute_config.MuteConfig: + r"""Gets a mute config. If no location is specified, + default is global. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_get_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetMuteConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_mute_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.GetMuteConfigRequest, dict]): + The request object. Request message for retrieving a mute + config. If no location is specified, + default is global. + name (str): + Required. Name of the mute config to retrieve. The + following list shows some examples of the format: + + - ``organizations/{organization}/muteConfigs/{config_id}`` + - + + ``organizations/{organization}/locations/{location}/muteConfigs/{config_id}`` + + - ``folders/{folder}/muteConfigs/{config_id}`` + - ``folders/{folder}/locations/{location}/muteConfigs/{config_id}`` + - ``projects/{project}/muteConfigs/{config_id}`` + - ``projects/{project}/locations/{location}/muteConfigs/{config_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.MuteConfig: + A mute config is a Cloud SCC resource + that contains the configuration to mute + create/update events of findings. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.GetMuteConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.GetMuteConfigRequest): + request = securitycenter_service.GetMuteConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_mute_config] + + header_params = {} + + routing_param_regex = re.compile( + "^projects/[^/]+/locations/(?P[^/]+)/muteConfigs/[^/]+$" + ) + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + routing_param_regex = re.compile( + "^organizations/[^/]+/locations/(?P[^/]+)/muteConfigs/[^/]+$" + ) + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + routing_param_regex = re.compile( + "^folders/[^/]+/locations/(?P[^/]+)/muteConfigs/[^/]+$" + ) + regex_match = routing_param_regex.match(request.name) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_notification_config( + self, + request: Optional[ + Union[securitycenter_service.GetNotificationConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> notification_config.NotificationConfig: + r"""Gets a notification config. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_get_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetNotificationConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_notification_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.GetNotificationConfigRequest, dict]): + The request object. Request message for getting a + notification config. + name (str): + Required. Name of the notification config to get. The + following list shows some examples of the format: + + - + + ``organizations/[organization_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + + ``folders/[folder_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + + ``projects/[project_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.NotificationConfig: + Cloud Security Command Center (Cloud + SCC) notification configs. + A notification config is a Cloud SCC + resource that contains the configuration + to send notifications for create/update + events of findings, assets and etc. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.GetNotificationConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.GetNotificationConfigRequest): + request = securitycenter_service.GetNotificationConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_notification_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_resource_value_config( + self, + request: Optional[ + Union[securitycenter_service.GetResourceValueConfigRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource_value_config.ResourceValueConfig: + r"""Gets a ResourceValueConfig. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_get_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetResourceValueConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_resource_value_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.GetResourceValueConfigRequest, dict]): + The request object. Request message to get resource value + config + name (str): + Required. Name of the resource value config to retrieve. + Its format is + organizations/{organization}/resourceValueConfigs/{config_id}. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.ResourceValueConfig: + A resource value config (RVC) is a + mapping configuration of user's + resources to resource values. Used in + Attack path simulations. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.GetResourceValueConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, securitycenter_service.GetResourceValueConfigRequest + ): + request = securitycenter_service.GetResourceValueConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.get_resource_value_config + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_source( + self, + request: Optional[Union[securitycenter_service.GetSourceRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> source.Source: + r"""Gets a source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_get_source(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetSourceRequest( + name="name_value", + ) + + # Make the request + response = client.get_source(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.GetSourceRequest, dict]): + The request object. Request message for getting a source. + name (str): + Required. Relative resource name of the source. Its + format is + "organizations/[organization_id]/source/[source_id]". + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Source: + Security Command Center finding + source. A finding source is an entity or + a mechanism that can produce a finding. + A source is like a container of findings + that come from the same scanner, logger, + monitor, and other tools. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.GetSourceRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.GetSourceRequest): + request = securitycenter_service.GetSourceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_source] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def group_findings( + self, + request: Optional[ + Union[securitycenter_service.GroupFindingsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + group_by: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.GroupFindingsPager: + r"""Filters an organization or source's findings and groups them by + their specified properties in a location. If no location is + specified, findings are assumed to be in global + + To group across all sources provide a ``-`` as the source id. + The following list shows some examples: + + - ``/v2/organizations/{organization_id}/sources/-/findings`` + - + + ``/v2/organizations/{organization_id}/sources/-/locations/{location_id}/findings`` + + - ``/v2/folders/{folder_id}/sources/-/findings`` + - ``/v2/folders/{folder_id}/sources/-/locations/{location_id}/findings`` + - ``/v2/projects/{project_id}/sources/-/findings`` + - ``/v2/projects/{project_id}/sources/-/locations/{location_id}/findings`` + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_group_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GroupFindingsRequest( + parent="parent_value", + group_by="group_by_value", + ) + + # Make the request + page_result = client.group_findings(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.GroupFindingsRequest, dict]): + The request object. Request message for grouping by + findings. + parent (str): + Required. Name of the source to groupBy. If no location + is specified, finding is assumed to be in global. The + following list shows some examples: + + - ``organizations/[organization_id]/sources/[source_id]`` + - + + ``organizations/[organization_id]/sources/[source_id]/locations/[location_id]`` + + - ``folders/[folder_id]/sources/[source_id]`` + - ``folders/[folder_id]/sources/[source_id]/locations/[location_id]`` + - ``projects/[project_id]/sources/[source_id]`` + - ``projects/[project_id]/sources/[source_id]/locations/[location_id]`` + + To groupBy across all sources provide a source_id of + ``-``. The following list shows some examples: + + - ``organizations/{organization_id}/sources/-`` + - ``organizations/{organization_id}/sources/-/locations/[location_id]`` + - ``folders/{folder_id}/sources/-`` + - ``folders/{folder_id}/sources/-/locations/[location_id]`` + - ``projects/{project_id}/sources/-`` + - ``projects/{project_id}/sources/-/locations/[location_id]`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + group_by (str): + Required. Expression that defines what assets fields to + use for grouping. The string value should follow SQL + syntax: comma separated list of fields. For example: + "parent,resource_name". + + The following fields are supported: + + - resource_name + - category + - state + - parent + - severity + + This corresponds to the ``group_by`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.GroupFindingsPager: + Response message for group by + findings. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, group_by]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.GroupFindingsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.GroupFindingsRequest): + request = securitycenter_service.GroupFindingsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if group_by is not None: + request.group_by = group_by + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.group_findings] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.GroupFindingsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_attack_paths( + self, + request: Optional[ + Union[securitycenter_service.ListAttackPathsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListAttackPathsPager: + r"""Lists the attack paths for a set of simulation + results or valued resources and filter. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_list_attack_paths(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListAttackPathsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_attack_paths(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.ListAttackPathsRequest, dict]): + The request object. Request message for listing the + attack paths for a given simulation or + valued resource. + parent (str): + Required. Name of parent to list attack paths. + + Valid formats: "organizations/{organization}", + "organizations/{organization}/simulations/{simulation}" + "organizations/{organization}/simulations/{simulation}/attackExposureResults/{attack_exposure_result_v2}" + "organizations/{organization}/simulations/{simulation}/valuedResources/{valued_resource}" + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListAttackPathsPager: + Response message for listing the + attack paths for a given simulation or + valued resource. + + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.ListAttackPathsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.ListAttackPathsRequest): + request = securitycenter_service.ListAttackPathsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_attack_paths] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListAttackPathsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_big_query_exports( + self, + request: Optional[ + Union[securitycenter_service.ListBigQueryExportsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListBigQueryExportsPager: + r"""Lists BigQuery exports. Note that when requesting + BigQuery exports at a given level all exports under that + level are also returned e.g. if requesting BigQuery + exports under a folder, then all BigQuery exports + immediately under the folder plus the ones created under + the projects within the folder are returned. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_list_big_query_exports(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListBigQueryExportsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_big_query_exports(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.ListBigQueryExportsRequest, dict]): + The request object. Request message for listing BigQuery + exports at a given scope e.g. + organization, folder or project. + parent (str): + Required. The parent, which owns the collection of + BigQuery exports. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListBigQueryExportsPager: + Response message for listing BigQuery + exports. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.ListBigQueryExportsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.ListBigQueryExportsRequest): + request = securitycenter_service.ListBigQueryExportsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_big_query_exports] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListBigQueryExportsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_findings( + self, + request: Optional[ + Union[securitycenter_service.ListFindingsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListFindingsPager: + r"""Lists an organization or source's findings. + + To list across all sources for a given location provide a ``-`` + as the source id. If no location is specified, finding are + assumed to be in global. The following list shows some examples: + + - ``/v2/organizations/{organization_id}/sources/-/findings`` + - + + ``/v2/organizations/{organization_id}/sources/-/locations/{location_id}/findings`` + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_list_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListFindingsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_findings(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.ListFindingsRequest, dict]): + The request object. Request message for listing findings. + parent (str): + Required. Name of the source the findings belong to. If + no location is specified, the default is global. The + following list shows some examples: + + - ``organizations/[organization_id]/sources/[source_id]`` + - + + ``organizations/[organization_id]/sources/[source_id]/locations/[location_id]`` + + - ``folders/[folder_id]/sources/[source_id]`` + - ``folders/[folder_id]/sources/[source_id]/locations/[location_id]`` + - ``projects/[project_id]/sources/[source_id]`` + - ``projects/[project_id]/sources/[source_id]/locations/[location_id]`` + + To list across all sources provide a source_id of ``-``. + The following list shows some examples: + + - ``organizations/{organization_id}/sources/-`` + - ``organizations/{organization_id}/sources/-/locations/{location_id}`` + - ``folders/{folder_id}/sources/-`` + - ``folders/{folder_id}/sources/-locations/{location_id}`` + - ``projects/{projects_id}/sources/-`` + - ``projects/{projects_id}/sources/-/locations/{location_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListFindingsPager: + Response message for listing + findings. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.ListFindingsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.ListFindingsRequest): + request = securitycenter_service.ListFindingsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_findings] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListFindingsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_mute_configs( + self, + request: Optional[ + Union[securitycenter_service.ListMuteConfigsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListMuteConfigsPager: + r"""Lists mute configs. If no location is specified, + default is global. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_list_mute_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListMuteConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_mute_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.ListMuteConfigsRequest, dict]): + The request object. Request message for listing mute + configs at a given scope e.g. + organization, folder or project. If no + location is specified, default is + global. + parent (str): + Required. The parent, which owns the collection of mute + configs. Its format is + "organizations/[organization_id]", + "folders/[folder_id]", "projects/[project_id]", + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListMuteConfigsPager: + Response message for listing mute + configs. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.ListMuteConfigsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.ListMuteConfigsRequest): + request = securitycenter_service.ListMuteConfigsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_mute_configs] + + header_params = {} + + routing_param_regex = re.compile( + "^projects/[^/]+/locations/(?P[^/]+)/muteConfigs$" + ) + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + routing_param_regex = re.compile( + "^organizations/[^/]+/locations/(?P[^/]+)/muteConfigs$" + ) + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + routing_param_regex = re.compile( + "^folders/[^/]+/locations/(?P[^/]+)/muteConfigs$" + ) + regex_match = routing_param_regex.match(request.parent) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListMuteConfigsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_notification_configs( + self, + request: Optional[ + Union[securitycenter_service.ListNotificationConfigsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListNotificationConfigsPager: + r"""Lists notification configs. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_list_notification_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListNotificationConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_notification_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.ListNotificationConfigsRequest, dict]): + The request object. Request message for listing + notification configs. + parent (str): + Required. The name of the parent in which to list the + notification configurations. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListNotificationConfigsPager: + Response message for listing + notification configs. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.ListNotificationConfigsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, securitycenter_service.ListNotificationConfigsRequest + ): + request = securitycenter_service.ListNotificationConfigsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_notification_configs + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListNotificationConfigsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_resource_value_configs( + self, + request: Optional[ + Union[securitycenter_service.ListResourceValueConfigsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListResourceValueConfigsPager: + r"""Lists all ResourceValueConfigs. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_list_resource_value_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListResourceValueConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_resource_value_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.ListResourceValueConfigsRequest, dict]): + The request object. Request message to list resource + value configs of a parent + parent (str): + Required. The parent, which owns the collection of + resource value configs. Its format is + "organizations/[organization_id]" + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListResourceValueConfigsPager: + Response message to list resource + value configs + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.ListResourceValueConfigsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, securitycenter_service.ListResourceValueConfigsRequest + ): + request = securitycenter_service.ListResourceValueConfigsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_resource_value_configs + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListResourceValueConfigsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_sources( + self, + request: Optional[ + Union[securitycenter_service.ListSourcesRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListSourcesPager: + r"""Lists all sources belonging to an organization. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_list_sources(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListSourcesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_sources(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.ListSourcesRequest, dict]): + The request object. Request message for listing sources. + parent (str): + Required. Resource name of the parent of sources to + list. Its format should be + "organizations/[organization_id]", + "folders/[folder_id]", or "projects/[project_id]". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListSourcesPager: + Response message for listing sources. + + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.ListSourcesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.ListSourcesRequest): + request = securitycenter_service.ListSourcesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_sources] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListSourcesPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_valued_resources( + self, + request: Optional[ + Union[securitycenter_service.ListValuedResourcesRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListValuedResourcesPager: + r"""Lists the valued resources for a set of simulation + results and filter. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_list_valued_resources(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListValuedResourcesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_valued_resources(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.ListValuedResourcesRequest, dict]): + The request object. Request message for listing the + valued resources for a given simulation. + parent (str): + Required. Name of parent to list exposed resources. + + Valid formats: "organizations/{organization}", + "organizations/{organization}/simulations/{simulation}" + "organizations/{organization}/simulations/{simulation}/attackExposureResults/{attack_exposure_result_v2}" + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.services.security_center.pagers.ListValuedResourcesPager: + Response message for listing the + valued resources for a given simulation. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.ListValuedResourcesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.ListValuedResourcesRequest): + request = securitycenter_service.ListValuedResourcesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_valued_resources] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListValuedResourcesPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def set_finding_state( + self, + request: Optional[ + Union[securitycenter_service.SetFindingStateRequest, dict] + ] = None, + *, + name: Optional[str] = None, + state: Optional[finding.Finding.State] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> finding.Finding: + r"""Updates the state of a finding. If no location is + specified, finding is assumed to be in global + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_set_finding_state(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.SetFindingStateRequest( + name="name_value", + state="INACTIVE", + ) + + # Make the request + response = client.set_finding_state(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.SetFindingStateRequest, dict]): + The request object. Request message for updating a + finding's state. + name (str): + Required. The `relative resource + name `__ + of the finding. If no location is specified, finding is + assumed to be in global. The following list shows some + examples: + + - + + ``organizations/{organization_id}/sources/{source_id}/findings/{finding_id}`` + + + ``organizations/{organization_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``folders/{folder_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``folders/{folder_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``projects/{project_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``projects/{project_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + state (google.cloud.securitycenter_v2.types.Finding.State): + Required. The desired State of the + finding. + + This corresponds to the ``state`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, state]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.SetFindingStateRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.SetFindingStateRequest): + request = securitycenter_service.SetFindingStateRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if state is not None: + request.state = state + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_finding_state] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def set_iam_policy( + self, + request: Optional[Union[iam_policy_pb2.SetIamPolicyRequest, dict]] = None, + *, + resource: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> policy_pb2.Policy: + r"""Sets the access control policy on the specified + Source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + from google.iam.v1 import iam_policy_pb2 # type: ignore + + def sample_set_iam_policy(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = iam_policy_pb2.SetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = client.set_iam_policy(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]): + The request object. Request message for ``SetIamPolicy`` method. + resource (str): + REQUIRED: The resource for which the + policy is being specified. See the + operation documentation for the + appropriate value for this field. + + This corresponds to the ``resource`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.iam.v1.policy_pb2.Policy: + An Identity and Access Management (IAM) policy, which specifies access + controls for Google Cloud resources. + + A Policy is a collection of bindings. A binding binds + one or more members, or principals, to a single role. + Principals can be user accounts, service accounts, + Google groups, and domains (such as G Suite). A role + is a named list of permissions; each role can be an + IAM predefined role or a user-created custom role. + + For some types of Google Cloud resources, a binding + can also specify a condition, which is a logical + expression that allows access to a resource only if + the expression evaluates to true. A condition can add + constraints based on attributes of the request, the + resource, or both. To learn which resources support + conditions in their IAM policies, see the [IAM + documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies). + + **JSON example:** + + :literal:`\` { "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')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \` + + **YAML example:** + + :literal:`\` 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') etag: BwWWja0YfJA= version: 3`\ \` + + For a description of IAM and its features, see the + [IAM + documentation](\ https://cloud.google.com/iam/docs/). + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + if isinstance(request, dict): + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + request = iam_policy_pb2.SetIamPolicyRequest(**request) + elif not request: + # Null request, just make one. + request = iam_policy_pb2.SetIamPolicyRequest() + if resource is not None: + request.resource = resource + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_iam_policy] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def set_mute( + self, + request: Optional[Union[securitycenter_service.SetMuteRequest, dict]] = None, + *, + name: Optional[str] = None, + mute: Optional[finding.Finding.Mute] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> finding.Finding: + r"""Updates the mute state of a finding. If no location + is specified, finding is assumed to be in global + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_set_mute(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.SetMuteRequest( + name="name_value", + mute="UNDEFINED", + ) + + # Make the request + response = client.set_mute(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.SetMuteRequest, dict]): + The request object. Request message for updating a + finding's mute status. + name (str): + Required. The `relative resource + name `__ + of the finding. If no location is specified, finding is + assumed to be in global. The following list shows some + examples: + + - + + ``organizations/{organization_id}/sources/{source_id}/findings/{finding_id}`` + + + ``organizations/{organization_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``folders/{folder_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``folders/{folder_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``projects/{project_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``projects/{project_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mute (google.cloud.securitycenter_v2.types.Finding.Mute): + Required. The desired state of the + Mute. + + This corresponds to the ``mute`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, mute]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.SetMuteRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.SetMuteRequest): + request = securitycenter_service.SetMuteRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if mute is not None: + request.mute = mute + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_mute] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def test_iam_permissions( + self, + request: Optional[Union[iam_policy_pb2.TestIamPermissionsRequest, dict]] = None, + *, + resource: Optional[str] = None, + permissions: Optional[MutableSequence[str]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> iam_policy_pb2.TestIamPermissionsResponse: + r"""Returns the permissions that a caller has on the + specified source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + from google.iam.v1 import iam_policy_pb2 # type: ignore + + def sample_test_iam_permissions(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = iam_policy_pb2.TestIamPermissionsRequest( + resource="resource_value", + permissions=['permissions_value1', 'permissions_value2'], + ) + + # Make the request + response = client.test_iam_permissions(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]): + The request object. Request message for ``TestIamPermissions`` method. + resource (str): + REQUIRED: The resource for which the + policy detail is being requested. See + the operation documentation for the + appropriate value for this field. + + This corresponds to the ``resource`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + permissions (MutableSequence[str]): + The set of permissions to check for the ``resource``. + Permissions with wildcards (such as '*' or 'storage.*') + are not allowed. For more information see `IAM + Overview `__. + + This corresponds to the ``permissions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse: + Response message for TestIamPermissions method. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource, permissions]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + if isinstance(request, dict): + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + request = iam_policy_pb2.TestIamPermissionsRequest(**request) + elif not request: + # Null request, just make one. + request = iam_policy_pb2.TestIamPermissionsRequest() + if resource is not None: + request.resource = resource + if permissions: + request.permissions.extend(permissions) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.test_iam_permissions] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_big_query_export( + self, + request: Optional[ + Union[securitycenter_service.UpdateBigQueryExportRequest, dict] + ] = None, + *, + big_query_export: Optional[bigquery_export.BigQueryExport] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bigquery_export.BigQueryExport: + r"""Updates a BigQuery export. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_update_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateBigQueryExportRequest( + ) + + # Make the request + response = client.update_big_query_export(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.UpdateBigQueryExportRequest, dict]): + The request object. Request message for updating a + BigQuery export. + big_query_export (google.cloud.securitycenter_v2.types.BigQueryExport): + Required. The BigQuery export being + updated. + + This corresponds to the ``big_query_export`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The list of fields to be updated. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.BigQueryExport: + Configures how to deliver Findings to + BigQuery Instance. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([big_query_export, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.UpdateBigQueryExportRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.UpdateBigQueryExportRequest): + request = securitycenter_service.UpdateBigQueryExportRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if big_query_export is not None: + request.big_query_export = big_query_export + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_big_query_export] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("big_query_export.name", request.big_query_export.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_external_system( + self, + request: Optional[ + Union[securitycenter_service.UpdateExternalSystemRequest, dict] + ] = None, + *, + external_system: Optional[gcs_external_system.ExternalSystem] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_external_system.ExternalSystem: + r"""Updates external system. This is for a given finding. + If no location is specified, finding is assumed to be in + global + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_update_external_system(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateExternalSystemRequest( + ) + + # Make the request + response = client.update_external_system(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.UpdateExternalSystemRequest, dict]): + The request object. Request message for updating a + ExternalSystem resource. + external_system (google.cloud.securitycenter_v2.types.ExternalSystem): + Required. The external system + resource to update. + + This corresponds to the ``external_system`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask to use when updating + the external system resource. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.ExternalSystem: + Representation of third party + SIEM/SOAR fields within SCC. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([external_system, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.UpdateExternalSystemRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.UpdateExternalSystemRequest): + request = securitycenter_service.UpdateExternalSystemRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if external_system is not None: + request.external_system = external_system + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_external_system] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("external_system.name", request.external_system.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_finding( + self, + request: Optional[ + Union[securitycenter_service.UpdateFindingRequest, dict] + ] = None, + *, + finding: Optional[gcs_finding.Finding] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_finding.Finding: + r"""Creates or updates a finding. If no location is + specified, finding is assumed to be in global. The + corresponding source must exist for a finding creation + to succeed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_update_finding(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateFindingRequest( + ) + + # Make the request + response = client.update_finding(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.UpdateFindingRequest, dict]): + The request object. Request message for updating or + creating a finding. + finding (google.cloud.securitycenter_v2.types.Finding): + Required. The finding resource to update or create if it + does not already exist. parent, security_marks, and + update_time will be ignored. + + In the case of creation, the finding id portion of the + name must be alphanumeric and less than or equal to 32 + characters and greater than 0 characters in length. + + This corresponds to the ``finding`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask to use when updating the finding resource. + This field should not be specified when creating a + finding. + + When updating a finding, an empty mask is treated as + updating all mutable fields and replacing + source_properties. Individual source_properties can be + added/updated by using "source_properties." in the field + mask. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([finding, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.UpdateFindingRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.UpdateFindingRequest): + request = securitycenter_service.UpdateFindingRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if finding is not None: + request.finding = finding + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_finding] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("finding.name", request.finding.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_mute_config( + self, + request: Optional[ + Union[securitycenter_service.UpdateMuteConfigRequest, dict] + ] = None, + *, + mute_config: Optional[gcs_mute_config.MuteConfig] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_mute_config.MuteConfig: + r"""Updates a mute config. If no location is specified, + default is global. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_update_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + mute_config = securitycenter_v2.MuteConfig() + mute_config.filter = "filter_value" + mute_config.type_ = "STATIC" + + request = securitycenter_v2.UpdateMuteConfigRequest( + mute_config=mute_config, + ) + + # Make the request + response = client.update_mute_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.UpdateMuteConfigRequest, dict]): + The request object. Request message for updating a mute + config. + mute_config (google.cloud.securitycenter_v2.types.MuteConfig): + Required. The mute config being + updated. + + This corresponds to the ``mute_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The list of fields to be updated. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.MuteConfig: + A mute config is a Cloud SCC resource + that contains the configuration to mute + create/update events of findings. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([mute_config, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.UpdateMuteConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.UpdateMuteConfigRequest): + request = securitycenter_service.UpdateMuteConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if mute_config is not None: + request.mute_config = mute_config + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_mute_config] + + header_params = {} + + routing_param_regex = re.compile( + "^projects/[^/]+/locations/(?P[^/]+)/muteConfigs/[^/]+$" + ) + regex_match = routing_param_regex.match(request.mute_config.name) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + routing_param_regex = re.compile( + "^organizations/[^/]+/locations/(?P[^/]+)/muteConfigs/[^/]+$" + ) + regex_match = routing_param_regex.match(request.mute_config.name) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + routing_param_regex = re.compile( + "^folders/[^/]+/locations/(?P[^/]+)/muteConfigs/[^/]+$" + ) + regex_match = routing_param_regex.match(request.mute_config.name) + if regex_match and regex_match.group("location"): + header_params["location"] = regex_match.group("location") + + if header_params: + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(header_params), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_notification_config( + self, + request: Optional[ + Union[securitycenter_service.UpdateNotificationConfigRequest, dict] + ] = None, + *, + notification_config: Optional[ + gcs_notification_config.NotificationConfig + ] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_notification_config.NotificationConfig: + r"""Updates a notification config. The following update fields are + allowed: description, pubsub_topic, streaming_config.filter + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_update_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateNotificationConfigRequest( + ) + + # Make the request + response = client.update_notification_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.UpdateNotificationConfigRequest, dict]): + The request object. Request message for updating a + notification config. + notification_config (google.cloud.securitycenter_v2.types.NotificationConfig): + Required. The notification config to + update. + + This corresponds to the ``notification_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask to use when updating + the notification config. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.NotificationConfig: + Cloud Security Command Center (Cloud + SCC) notification configs. + A notification config is a Cloud SCC + resource that contains the configuration + to send notifications for create/update + events of findings, assets and etc. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([notification_config, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.UpdateNotificationConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, securitycenter_service.UpdateNotificationConfigRequest + ): + request = securitycenter_service.UpdateNotificationConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if notification_config is not None: + request.notification_config = notification_config + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.update_notification_config + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("notification_config.name", request.notification_config.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_resource_value_config( + self, + request: Optional[ + Union[securitycenter_service.UpdateResourceValueConfigRequest, dict] + ] = None, + *, + resource_value_config: Optional[ + gcs_resource_value_config.ResourceValueConfig + ] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_resource_value_config.ResourceValueConfig: + r"""Updates an existing ResourceValueConfigs with new + rules. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_update_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + resource_value_config = securitycenter_v2.ResourceValueConfig() + resource_value_config.tag_values = ['tag_values_value1', 'tag_values_value2'] + + request = securitycenter_v2.UpdateResourceValueConfigRequest( + resource_value_config=resource_value_config, + ) + + # Make the request + response = client.update_resource_value_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.UpdateResourceValueConfigRequest, dict]): + The request object. Request message to update resource + value config + resource_value_config (google.cloud.securitycenter_v2.types.ResourceValueConfig): + Required. The resource value config + being updated. + + This corresponds to the ``resource_value_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The list of fields to be updated. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.ResourceValueConfig: + A resource value config (RVC) is a + mapping configuration of user's + resources to resource values. Used in + Attack path simulations. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([resource_value_config, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.UpdateResourceValueConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, securitycenter_service.UpdateResourceValueConfigRequest + ): + request = securitycenter_service.UpdateResourceValueConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_value_config is not None: + request.resource_value_config = resource_value_config + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.update_resource_value_config + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_value_config.name", request.resource_value_config.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_security_marks( + self, + request: Optional[ + Union[securitycenter_service.UpdateSecurityMarksRequest, dict] + ] = None, + *, + security_marks: Optional[gcs_security_marks.SecurityMarks] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_security_marks.SecurityMarks: + r"""Updates security marks. For Finding Security marks, + if no location is specified, finding is assumed to be in + global. Assets Security Marks can only be accessed + through global endpoint. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_update_security_marks(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateSecurityMarksRequest( + ) + + # Make the request + response = client.update_security_marks(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.UpdateSecurityMarksRequest, dict]): + The request object. Request message for updating a + SecurityMarks resource. + security_marks (google.cloud.securitycenter_v2.types.SecurityMarks): + Required. The security marks resource + to update. + + This corresponds to the ``security_marks`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask to use when updating the security marks + resource. + + The field mask must not contain duplicate fields. If + empty or set to "marks", all marks will be replaced. + Individual marks can be updated using + "marks.". + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.SecurityMarks: + User specified security marks that + are attached to the parent Security + Command Center resource. Security marks + are scoped within a Security Command + Center organization -- they can be + modified and viewed by all users who + have proper permissions on the + organization. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([security_marks, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.UpdateSecurityMarksRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.UpdateSecurityMarksRequest): + request = securitycenter_service.UpdateSecurityMarksRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if security_marks is not None: + request.security_marks = security_marks + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_security_marks] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("security_marks.name", request.security_marks.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_source( + self, + request: Optional[ + Union[securitycenter_service.UpdateSourceRequest, dict] + ] = None, + *, + source: Optional[gcs_source.Source] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_source.Source: + r"""Updates a source. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import securitycenter_v2 + + def sample_update_source(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateSourceRequest( + ) + + # Make the request + response = client.update_source(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.securitycenter_v2.types.UpdateSourceRequest, dict]): + The request object. Request message for updating a + source. + source (google.cloud.securitycenter_v2.types.Source): + Required. The source resource to + update. + + This corresponds to the ``source`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask to use when updating + the source resource. + If empty all mutable fields will be + updated. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.securitycenter_v2.types.Source: + Security Command Center finding + source. A finding source is an entity or + a mechanism that can produce a finding. + A source is like a container of findings + that come from the same scanner, logger, + monitor, and other tools. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([source, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a securitycenter_service.UpdateSourceRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, securitycenter_service.UpdateSourceRequest): + request = securitycenter_service.UpdateSourceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if source is not None: + request.source = source + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_source] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("source.name", request.source.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "SecurityCenterClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` 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): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # 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): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_operation( + self, + request: Optional[operations_pb2.DeleteOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a long-running operation. + + This method indicates that the client is no longer interested + in the operation result. It does not cancel the operation. + If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # 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): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.delete_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + Returns: + None + """ + # 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): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.cancel_operation, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +__all__ = ("SecurityCenterClient",) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/pagers.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/pagers.py new file mode 100644 index 000000000000..72a28476b4eb --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/pagers.py @@ -0,0 +1,1220 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, +) + +from google.cloud.securitycenter_v2.types import ( + attack_path, + bigquery_export, + mute_config, + notification_config, + resource_value_config, + securitycenter_service, + source, + valued_resource, +) + + +class GroupFindingsPager: + """A pager for iterating through ``group_findings`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.GroupFindingsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``group_by_results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``GroupFindings`` requests and continue to iterate + through the ``group_by_results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.GroupFindingsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., securitycenter_service.GroupFindingsResponse], + request: securitycenter_service.GroupFindingsRequest, + response: securitycenter_service.GroupFindingsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.GroupFindingsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.GroupFindingsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.GroupFindingsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[securitycenter_service.GroupFindingsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[securitycenter_service.GroupResult]: + for page in self.pages: + yield from page.group_by_results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class GroupFindingsAsyncPager: + """A pager for iterating through ``group_findings`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.GroupFindingsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``group_by_results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``GroupFindings`` requests and continue to iterate + through the ``group_by_results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.GroupFindingsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., Awaitable[securitycenter_service.GroupFindingsResponse]], + request: securitycenter_service.GroupFindingsRequest, + response: securitycenter_service.GroupFindingsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.GroupFindingsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.GroupFindingsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.GroupFindingsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[securitycenter_service.GroupFindingsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[securitycenter_service.GroupResult]: + async def async_generator(): + async for page in self.pages: + for response in page.group_by_results: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListAttackPathsPager: + """A pager for iterating through ``list_attack_paths`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListAttackPathsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``attack_paths`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListAttackPaths`` requests and continue to iterate + through the ``attack_paths`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListAttackPathsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., securitycenter_service.ListAttackPathsResponse], + request: securitycenter_service.ListAttackPathsRequest, + response: securitycenter_service.ListAttackPathsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListAttackPathsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListAttackPathsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListAttackPathsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[securitycenter_service.ListAttackPathsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[attack_path.AttackPath]: + for page in self.pages: + yield from page.attack_paths + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListAttackPathsAsyncPager: + """A pager for iterating through ``list_attack_paths`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListAttackPathsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``attack_paths`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListAttackPaths`` requests and continue to iterate + through the ``attack_paths`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListAttackPathsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[securitycenter_service.ListAttackPathsResponse] + ], + request: securitycenter_service.ListAttackPathsRequest, + response: securitycenter_service.ListAttackPathsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListAttackPathsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListAttackPathsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListAttackPathsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[securitycenter_service.ListAttackPathsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[attack_path.AttackPath]: + async def async_generator(): + async for page in self.pages: + for response in page.attack_paths: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListBigQueryExportsPager: + """A pager for iterating through ``list_big_query_exports`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListBigQueryExportsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``big_query_exports`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListBigQueryExports`` requests and continue to iterate + through the ``big_query_exports`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListBigQueryExportsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., securitycenter_service.ListBigQueryExportsResponse], + request: securitycenter_service.ListBigQueryExportsRequest, + response: securitycenter_service.ListBigQueryExportsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListBigQueryExportsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListBigQueryExportsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListBigQueryExportsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[securitycenter_service.ListBigQueryExportsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[bigquery_export.BigQueryExport]: + for page in self.pages: + yield from page.big_query_exports + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListBigQueryExportsAsyncPager: + """A pager for iterating through ``list_big_query_exports`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListBigQueryExportsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``big_query_exports`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListBigQueryExports`` requests and continue to iterate + through the ``big_query_exports`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListBigQueryExportsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[securitycenter_service.ListBigQueryExportsResponse] + ], + request: securitycenter_service.ListBigQueryExportsRequest, + response: securitycenter_service.ListBigQueryExportsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListBigQueryExportsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListBigQueryExportsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListBigQueryExportsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[securitycenter_service.ListBigQueryExportsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[bigquery_export.BigQueryExport]: + async def async_generator(): + async for page in self.pages: + for response in page.big_query_exports: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListFindingsPager: + """A pager for iterating through ``list_findings`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListFindingsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``list_findings_results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListFindings`` requests and continue to iterate + through the ``list_findings_results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListFindingsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., securitycenter_service.ListFindingsResponse], + request: securitycenter_service.ListFindingsRequest, + response: securitycenter_service.ListFindingsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListFindingsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListFindingsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListFindingsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[securitycenter_service.ListFindingsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__( + self, + ) -> Iterator[securitycenter_service.ListFindingsResponse.ListFindingsResult]: + for page in self.pages: + yield from page.list_findings_results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListFindingsAsyncPager: + """A pager for iterating through ``list_findings`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListFindingsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``list_findings_results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListFindings`` requests and continue to iterate + through the ``list_findings_results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListFindingsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., Awaitable[securitycenter_service.ListFindingsResponse]], + request: securitycenter_service.ListFindingsRequest, + response: securitycenter_service.ListFindingsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListFindingsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListFindingsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListFindingsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[securitycenter_service.ListFindingsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__( + self, + ) -> AsyncIterator[securitycenter_service.ListFindingsResponse.ListFindingsResult]: + async def async_generator(): + async for page in self.pages: + for response in page.list_findings_results: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListMuteConfigsPager: + """A pager for iterating through ``list_mute_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListMuteConfigsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``mute_configs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListMuteConfigs`` requests and continue to iterate + through the ``mute_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListMuteConfigsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., securitycenter_service.ListMuteConfigsResponse], + request: securitycenter_service.ListMuteConfigsRequest, + response: securitycenter_service.ListMuteConfigsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListMuteConfigsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListMuteConfigsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListMuteConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[securitycenter_service.ListMuteConfigsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[mute_config.MuteConfig]: + for page in self.pages: + yield from page.mute_configs + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListMuteConfigsAsyncPager: + """A pager for iterating through ``list_mute_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListMuteConfigsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``mute_configs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListMuteConfigs`` requests and continue to iterate + through the ``mute_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListMuteConfigsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[securitycenter_service.ListMuteConfigsResponse] + ], + request: securitycenter_service.ListMuteConfigsRequest, + response: securitycenter_service.ListMuteConfigsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListMuteConfigsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListMuteConfigsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListMuteConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[securitycenter_service.ListMuteConfigsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[mute_config.MuteConfig]: + async def async_generator(): + async for page in self.pages: + for response in page.mute_configs: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListNotificationConfigsPager: + """A pager for iterating through ``list_notification_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListNotificationConfigsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``notification_configs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListNotificationConfigs`` requests and continue to iterate + through the ``notification_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListNotificationConfigsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., securitycenter_service.ListNotificationConfigsResponse], + request: securitycenter_service.ListNotificationConfigsRequest, + response: securitycenter_service.ListNotificationConfigsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListNotificationConfigsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListNotificationConfigsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListNotificationConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[securitycenter_service.ListNotificationConfigsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[notification_config.NotificationConfig]: + for page in self.pages: + yield from page.notification_configs + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListNotificationConfigsAsyncPager: + """A pager for iterating through ``list_notification_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListNotificationConfigsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``notification_configs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListNotificationConfigs`` requests and continue to iterate + through the ``notification_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListNotificationConfigsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[securitycenter_service.ListNotificationConfigsResponse] + ], + request: securitycenter_service.ListNotificationConfigsRequest, + response: securitycenter_service.ListNotificationConfigsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListNotificationConfigsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListNotificationConfigsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListNotificationConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[securitycenter_service.ListNotificationConfigsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[notification_config.NotificationConfig]: + async def async_generator(): + async for page in self.pages: + for response in page.notification_configs: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListResourceValueConfigsPager: + """A pager for iterating through ``list_resource_value_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListResourceValueConfigsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``resource_value_configs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListResourceValueConfigs`` requests and continue to iterate + through the ``resource_value_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListResourceValueConfigsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., securitycenter_service.ListResourceValueConfigsResponse], + request: securitycenter_service.ListResourceValueConfigsRequest, + response: securitycenter_service.ListResourceValueConfigsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListResourceValueConfigsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListResourceValueConfigsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListResourceValueConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[securitycenter_service.ListResourceValueConfigsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[resource_value_config.ResourceValueConfig]: + for page in self.pages: + yield from page.resource_value_configs + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListResourceValueConfigsAsyncPager: + """A pager for iterating through ``list_resource_value_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListResourceValueConfigsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``resource_value_configs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListResourceValueConfigs`` requests and continue to iterate + through the ``resource_value_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListResourceValueConfigsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[securitycenter_service.ListResourceValueConfigsResponse] + ], + request: securitycenter_service.ListResourceValueConfigsRequest, + response: securitycenter_service.ListResourceValueConfigsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListResourceValueConfigsRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListResourceValueConfigsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListResourceValueConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[securitycenter_service.ListResourceValueConfigsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[resource_value_config.ResourceValueConfig]: + async def async_generator(): + async for page in self.pages: + for response in page.resource_value_configs: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListSourcesPager: + """A pager for iterating through ``list_sources`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListSourcesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``sources`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListSources`` requests and continue to iterate + through the ``sources`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListSourcesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., securitycenter_service.ListSourcesResponse], + request: securitycenter_service.ListSourcesRequest, + response: securitycenter_service.ListSourcesResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListSourcesRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListSourcesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListSourcesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[securitycenter_service.ListSourcesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[source.Source]: + for page in self.pages: + yield from page.sources + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListSourcesAsyncPager: + """A pager for iterating through ``list_sources`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListSourcesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``sources`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListSources`` requests and continue to iterate + through the ``sources`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListSourcesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., Awaitable[securitycenter_service.ListSourcesResponse]], + request: securitycenter_service.ListSourcesRequest, + response: securitycenter_service.ListSourcesResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListSourcesRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListSourcesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListSourcesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[securitycenter_service.ListSourcesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[source.Source]: + async def async_generator(): + async for page in self.pages: + for response in page.sources: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListValuedResourcesPager: + """A pager for iterating through ``list_valued_resources`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListValuedResourcesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``valued_resources`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListValuedResources`` requests and continue to iterate + through the ``valued_resources`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListValuedResourcesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., securitycenter_service.ListValuedResourcesResponse], + request: securitycenter_service.ListValuedResourcesRequest, + response: securitycenter_service.ListValuedResourcesResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListValuedResourcesRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListValuedResourcesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListValuedResourcesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[securitycenter_service.ListValuedResourcesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[valued_resource.ValuedResource]: + for page in self.pages: + yield from page.valued_resources + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListValuedResourcesAsyncPager: + """A pager for iterating through ``list_valued_resources`` requests. + + This class thinly wraps an initial + :class:`google.cloud.securitycenter_v2.types.ListValuedResourcesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``valued_resources`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListValuedResources`` requests and continue to iterate + through the ``valued_resources`` field on the + corresponding responses. + + All the usual :class:`google.cloud.securitycenter_v2.types.ListValuedResourcesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[securitycenter_service.ListValuedResourcesResponse] + ], + request: securitycenter_service.ListValuedResourcesRequest, + response: securitycenter_service.ListValuedResourcesResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.securitycenter_v2.types.ListValuedResourcesRequest): + The initial request object. + response (google.cloud.securitycenter_v2.types.ListValuedResourcesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = securitycenter_service.ListValuedResourcesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[securitycenter_service.ListValuedResourcesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[valued_resource.ValuedResource]: + async def async_generator(): + async for page in self.pages: + for response in page.valued_resources: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/__init__.py new file mode 100644 index 000000000000..441ce35301f9 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import SecurityCenterTransport +from .grpc import SecurityCenterGrpcTransport +from .grpc_asyncio import SecurityCenterGrpcAsyncIOTransport +from .rest import SecurityCenterRestInterceptor, SecurityCenterRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[SecurityCenterTransport]] +_transport_registry["grpc"] = SecurityCenterGrpcTransport +_transport_registry["grpc_asyncio"] = SecurityCenterGrpcAsyncIOTransport +_transport_registry["rest"] = SecurityCenterRestTransport + +__all__ = ( + "SecurityCenterTransport", + "SecurityCenterGrpcTransport", + "SecurityCenterGrpcAsyncIOTransport", + "SecurityCenterRestTransport", + "SecurityCenterRestInterceptor", +) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/base.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/base.py new file mode 100644 index 000000000000..ae3c5c3559e8 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/base.py @@ -0,0 +1,827 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.iam.v1 import iam_policy_pb2 # type: ignore +from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +from google.cloud.securitycenter_v2 import gapic_version as package_version +from google.cloud.securitycenter_v2.types import securitycenter_service, simulation +from google.cloud.securitycenter_v2.types import external_system as gcs_external_system +from google.cloud.securitycenter_v2.types import ( + notification_config as gcs_notification_config, +) +from google.cloud.securitycenter_v2.types import ( + resource_value_config as gcs_resource_value_config, +) +from google.cloud.securitycenter_v2.types import security_marks as gcs_security_marks +from google.cloud.securitycenter_v2.types import bigquery_export +from google.cloud.securitycenter_v2.types import finding +from google.cloud.securitycenter_v2.types import finding as gcs_finding +from google.cloud.securitycenter_v2.types import mute_config +from google.cloud.securitycenter_v2.types import mute_config as gcs_mute_config +from google.cloud.securitycenter_v2.types import notification_config +from google.cloud.securitycenter_v2.types import resource_value_config +from google.cloud.securitycenter_v2.types import source +from google.cloud.securitycenter_v2.types import source as gcs_source +from google.cloud.securitycenter_v2.types import valued_resource + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + + +class SecurityCenterTransport(abc.ABC): + """Abstract transport class for SecurityCenter.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + DEFAULT_HOST: str = "securitycenter.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'securitycenter.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (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 + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.batch_create_resource_value_configs: gapic_v1.method.wrap_method( + self.batch_create_resource_value_configs, + default_timeout=None, + client_info=client_info, + ), + self.bulk_mute_findings: gapic_v1.method.wrap_method( + self.bulk_mute_findings, + default_timeout=None, + client_info=client_info, + ), + self.create_big_query_export: gapic_v1.method.wrap_method( + self.create_big_query_export, + default_timeout=None, + client_info=client_info, + ), + self.create_finding: gapic_v1.method.wrap_method( + self.create_finding, + default_timeout=None, + client_info=client_info, + ), + self.create_mute_config: gapic_v1.method.wrap_method( + self.create_mute_config, + default_timeout=None, + client_info=client_info, + ), + self.create_notification_config: gapic_v1.method.wrap_method( + self.create_notification_config, + default_timeout=None, + client_info=client_info, + ), + self.create_source: gapic_v1.method.wrap_method( + self.create_source, + default_timeout=None, + client_info=client_info, + ), + self.delete_big_query_export: gapic_v1.method.wrap_method( + self.delete_big_query_export, + default_timeout=None, + client_info=client_info, + ), + self.delete_mute_config: gapic_v1.method.wrap_method( + self.delete_mute_config, + default_timeout=None, + client_info=client_info, + ), + self.delete_notification_config: gapic_v1.method.wrap_method( + self.delete_notification_config, + default_timeout=None, + client_info=client_info, + ), + self.delete_resource_value_config: gapic_v1.method.wrap_method( + self.delete_resource_value_config, + default_timeout=None, + client_info=client_info, + ), + self.get_big_query_export: gapic_v1.method.wrap_method( + self.get_big_query_export, + default_timeout=None, + client_info=client_info, + ), + self.get_simulation: gapic_v1.method.wrap_method( + self.get_simulation, + default_timeout=None, + client_info=client_info, + ), + self.get_valued_resource: gapic_v1.method.wrap_method( + self.get_valued_resource, + default_timeout=None, + client_info=client_info, + ), + self.get_iam_policy: gapic_v1.method.wrap_method( + self.get_iam_policy, + default_timeout=None, + client_info=client_info, + ), + self.get_mute_config: gapic_v1.method.wrap_method( + self.get_mute_config, + default_timeout=None, + client_info=client_info, + ), + self.get_notification_config: gapic_v1.method.wrap_method( + self.get_notification_config, + default_timeout=None, + client_info=client_info, + ), + self.get_resource_value_config: gapic_v1.method.wrap_method( + self.get_resource_value_config, + default_timeout=None, + client_info=client_info, + ), + self.get_source: gapic_v1.method.wrap_method( + self.get_source, + default_timeout=None, + client_info=client_info, + ), + self.group_findings: gapic_v1.method.wrap_method( + self.group_findings, + default_timeout=None, + client_info=client_info, + ), + self.list_attack_paths: gapic_v1.method.wrap_method( + self.list_attack_paths, + default_timeout=None, + client_info=client_info, + ), + self.list_big_query_exports: gapic_v1.method.wrap_method( + self.list_big_query_exports, + default_timeout=None, + client_info=client_info, + ), + self.list_findings: gapic_v1.method.wrap_method( + self.list_findings, + default_timeout=None, + client_info=client_info, + ), + self.list_mute_configs: gapic_v1.method.wrap_method( + self.list_mute_configs, + default_timeout=None, + client_info=client_info, + ), + self.list_notification_configs: gapic_v1.method.wrap_method( + self.list_notification_configs, + default_timeout=None, + client_info=client_info, + ), + self.list_resource_value_configs: gapic_v1.method.wrap_method( + self.list_resource_value_configs, + default_timeout=None, + client_info=client_info, + ), + self.list_sources: gapic_v1.method.wrap_method( + self.list_sources, + default_timeout=None, + client_info=client_info, + ), + self.list_valued_resources: gapic_v1.method.wrap_method( + self.list_valued_resources, + default_timeout=None, + client_info=client_info, + ), + self.set_finding_state: gapic_v1.method.wrap_method( + self.set_finding_state, + default_timeout=None, + client_info=client_info, + ), + self.set_iam_policy: gapic_v1.method.wrap_method( + self.set_iam_policy, + default_timeout=None, + client_info=client_info, + ), + self.set_mute: gapic_v1.method.wrap_method( + self.set_mute, + default_timeout=None, + client_info=client_info, + ), + self.test_iam_permissions: gapic_v1.method.wrap_method( + self.test_iam_permissions, + default_timeout=None, + client_info=client_info, + ), + self.update_big_query_export: gapic_v1.method.wrap_method( + self.update_big_query_export, + default_timeout=None, + client_info=client_info, + ), + self.update_external_system: gapic_v1.method.wrap_method( + self.update_external_system, + default_timeout=None, + client_info=client_info, + ), + self.update_finding: gapic_v1.method.wrap_method( + self.update_finding, + default_timeout=None, + client_info=client_info, + ), + self.update_mute_config: gapic_v1.method.wrap_method( + self.update_mute_config, + default_timeout=None, + client_info=client_info, + ), + self.update_notification_config: gapic_v1.method.wrap_method( + self.update_notification_config, + default_timeout=None, + client_info=client_info, + ), + self.update_resource_value_config: gapic_v1.method.wrap_method( + self.update_resource_value_config, + default_timeout=None, + client_info=client_info, + ), + self.update_security_marks: gapic_v1.method.wrap_method( + self.update_security_marks, + default_timeout=None, + client_info=client_info, + ), + self.update_source: gapic_v1.method.wrap_method( + self.update_source, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def batch_create_resource_value_configs( + self, + ) -> Callable[ + [securitycenter_service.BatchCreateResourceValueConfigsRequest], + Union[ + securitycenter_service.BatchCreateResourceValueConfigsResponse, + Awaitable[securitycenter_service.BatchCreateResourceValueConfigsResponse], + ], + ]: + raise NotImplementedError() + + @property + def bulk_mute_findings( + self, + ) -> Callable[ + [securitycenter_service.BulkMuteFindingsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def create_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.CreateBigQueryExportRequest], + Union[ + bigquery_export.BigQueryExport, Awaitable[bigquery_export.BigQueryExport] + ], + ]: + raise NotImplementedError() + + @property + def create_finding( + self, + ) -> Callable[ + [securitycenter_service.CreateFindingRequest], + Union[gcs_finding.Finding, Awaitable[gcs_finding.Finding]], + ]: + raise NotImplementedError() + + @property + def create_mute_config( + self, + ) -> Callable[ + [securitycenter_service.CreateMuteConfigRequest], + Union[gcs_mute_config.MuteConfig, Awaitable[gcs_mute_config.MuteConfig]], + ]: + raise NotImplementedError() + + @property + def create_notification_config( + self, + ) -> Callable[ + [securitycenter_service.CreateNotificationConfigRequest], + Union[ + gcs_notification_config.NotificationConfig, + Awaitable[gcs_notification_config.NotificationConfig], + ], + ]: + raise NotImplementedError() + + @property + def create_source( + self, + ) -> Callable[ + [securitycenter_service.CreateSourceRequest], + Union[gcs_source.Source, Awaitable[gcs_source.Source]], + ]: + raise NotImplementedError() + + @property + def delete_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.DeleteBigQueryExportRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def delete_mute_config( + self, + ) -> Callable[ + [securitycenter_service.DeleteMuteConfigRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def delete_notification_config( + self, + ) -> Callable[ + [securitycenter_service.DeleteNotificationConfigRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def delete_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.DeleteResourceValueConfigRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def get_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.GetBigQueryExportRequest], + Union[ + bigquery_export.BigQueryExport, Awaitable[bigquery_export.BigQueryExport] + ], + ]: + raise NotImplementedError() + + @property + def get_simulation( + self, + ) -> Callable[ + [securitycenter_service.GetSimulationRequest], + Union[simulation.Simulation, Awaitable[simulation.Simulation]], + ]: + raise NotImplementedError() + + @property + def get_valued_resource( + self, + ) -> Callable[ + [securitycenter_service.GetValuedResourceRequest], + Union[ + valued_resource.ValuedResource, Awaitable[valued_resource.ValuedResource] + ], + ]: + raise NotImplementedError() + + @property + def get_iam_policy( + self, + ) -> Callable[ + [iam_policy_pb2.GetIamPolicyRequest], + Union[policy_pb2.Policy, Awaitable[policy_pb2.Policy]], + ]: + raise NotImplementedError() + + @property + def get_mute_config( + self, + ) -> Callable[ + [securitycenter_service.GetMuteConfigRequest], + Union[mute_config.MuteConfig, Awaitable[mute_config.MuteConfig]], + ]: + raise NotImplementedError() + + @property + def get_notification_config( + self, + ) -> Callable[ + [securitycenter_service.GetNotificationConfigRequest], + Union[ + notification_config.NotificationConfig, + Awaitable[notification_config.NotificationConfig], + ], + ]: + raise NotImplementedError() + + @property + def get_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.GetResourceValueConfigRequest], + Union[ + resource_value_config.ResourceValueConfig, + Awaitable[resource_value_config.ResourceValueConfig], + ], + ]: + raise NotImplementedError() + + @property + def get_source( + self, + ) -> Callable[ + [securitycenter_service.GetSourceRequest], + Union[source.Source, Awaitable[source.Source]], + ]: + raise NotImplementedError() + + @property + def group_findings( + self, + ) -> Callable[ + [securitycenter_service.GroupFindingsRequest], + Union[ + securitycenter_service.GroupFindingsResponse, + Awaitable[securitycenter_service.GroupFindingsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_attack_paths( + self, + ) -> Callable[ + [securitycenter_service.ListAttackPathsRequest], + Union[ + securitycenter_service.ListAttackPathsResponse, + Awaitable[securitycenter_service.ListAttackPathsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_big_query_exports( + self, + ) -> Callable[ + [securitycenter_service.ListBigQueryExportsRequest], + Union[ + securitycenter_service.ListBigQueryExportsResponse, + Awaitable[securitycenter_service.ListBigQueryExportsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_findings( + self, + ) -> Callable[ + [securitycenter_service.ListFindingsRequest], + Union[ + securitycenter_service.ListFindingsResponse, + Awaitable[securitycenter_service.ListFindingsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_mute_configs( + self, + ) -> Callable[ + [securitycenter_service.ListMuteConfigsRequest], + Union[ + securitycenter_service.ListMuteConfigsResponse, + Awaitable[securitycenter_service.ListMuteConfigsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_notification_configs( + self, + ) -> Callable[ + [securitycenter_service.ListNotificationConfigsRequest], + Union[ + securitycenter_service.ListNotificationConfigsResponse, + Awaitable[securitycenter_service.ListNotificationConfigsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_resource_value_configs( + self, + ) -> Callable[ + [securitycenter_service.ListResourceValueConfigsRequest], + Union[ + securitycenter_service.ListResourceValueConfigsResponse, + Awaitable[securitycenter_service.ListResourceValueConfigsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_sources( + self, + ) -> Callable[ + [securitycenter_service.ListSourcesRequest], + Union[ + securitycenter_service.ListSourcesResponse, + Awaitable[securitycenter_service.ListSourcesResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_valued_resources( + self, + ) -> Callable[ + [securitycenter_service.ListValuedResourcesRequest], + Union[ + securitycenter_service.ListValuedResourcesResponse, + Awaitable[securitycenter_service.ListValuedResourcesResponse], + ], + ]: + raise NotImplementedError() + + @property + def set_finding_state( + self, + ) -> Callable[ + [securitycenter_service.SetFindingStateRequest], + Union[finding.Finding, Awaitable[finding.Finding]], + ]: + raise NotImplementedError() + + @property + def set_iam_policy( + self, + ) -> Callable[ + [iam_policy_pb2.SetIamPolicyRequest], + Union[policy_pb2.Policy, Awaitable[policy_pb2.Policy]], + ]: + raise NotImplementedError() + + @property + def set_mute( + self, + ) -> Callable[ + [securitycenter_service.SetMuteRequest], + Union[finding.Finding, Awaitable[finding.Finding]], + ]: + raise NotImplementedError() + + @property + def test_iam_permissions( + self, + ) -> Callable[ + [iam_policy_pb2.TestIamPermissionsRequest], + Union[ + iam_policy_pb2.TestIamPermissionsResponse, + Awaitable[iam_policy_pb2.TestIamPermissionsResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.UpdateBigQueryExportRequest], + Union[ + bigquery_export.BigQueryExport, Awaitable[bigquery_export.BigQueryExport] + ], + ]: + raise NotImplementedError() + + @property + def update_external_system( + self, + ) -> Callable[ + [securitycenter_service.UpdateExternalSystemRequest], + Union[ + gcs_external_system.ExternalSystem, + Awaitable[gcs_external_system.ExternalSystem], + ], + ]: + raise NotImplementedError() + + @property + def update_finding( + self, + ) -> Callable[ + [securitycenter_service.UpdateFindingRequest], + Union[gcs_finding.Finding, Awaitable[gcs_finding.Finding]], + ]: + raise NotImplementedError() + + @property + def update_mute_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateMuteConfigRequest], + Union[gcs_mute_config.MuteConfig, Awaitable[gcs_mute_config.MuteConfig]], + ]: + raise NotImplementedError() + + @property + def update_notification_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateNotificationConfigRequest], + Union[ + gcs_notification_config.NotificationConfig, + Awaitable[gcs_notification_config.NotificationConfig], + ], + ]: + raise NotImplementedError() + + @property + def update_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateResourceValueConfigRequest], + Union[ + gcs_resource_value_config.ResourceValueConfig, + Awaitable[gcs_resource_value_config.ResourceValueConfig], + ], + ]: + raise NotImplementedError() + + @property + def update_security_marks( + self, + ) -> Callable[ + [securitycenter_service.UpdateSecurityMarksRequest], + Union[ + gcs_security_marks.SecurityMarks, + Awaitable[gcs_security_marks.SecurityMarks], + ], + ]: + raise NotImplementedError() + + @property + def update_source( + self, + ) -> Callable[ + [securitycenter_service.UpdateSourceRequest], + Union[gcs_source.Source, Awaitable[gcs_source.Source]], + ]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None,]: + raise NotImplementedError() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None,]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("SecurityCenterTransport",) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/grpc.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/grpc.py new file mode 100644 index 000000000000..05e0d73b7991 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/grpc.py @@ -0,0 +1,1527 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from typing import Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers, operations_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.iam.v1 import iam_policy_pb2 # type: ignore +from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +import grpc # type: ignore + +from google.cloud.securitycenter_v2.types import securitycenter_service, simulation +from google.cloud.securitycenter_v2.types import external_system as gcs_external_system +from google.cloud.securitycenter_v2.types import ( + notification_config as gcs_notification_config, +) +from google.cloud.securitycenter_v2.types import ( + resource_value_config as gcs_resource_value_config, +) +from google.cloud.securitycenter_v2.types import security_marks as gcs_security_marks +from google.cloud.securitycenter_v2.types import bigquery_export +from google.cloud.securitycenter_v2.types import finding +from google.cloud.securitycenter_v2.types import finding as gcs_finding +from google.cloud.securitycenter_v2.types import mute_config +from google.cloud.securitycenter_v2.types import mute_config as gcs_mute_config +from google.cloud.securitycenter_v2.types import notification_config +from google.cloud.securitycenter_v2.types import resource_value_config +from google.cloud.securitycenter_v2.types import source +from google.cloud.securitycenter_v2.types import source as gcs_source +from google.cloud.securitycenter_v2.types import valued_resource + +from .base import DEFAULT_CLIENT_INFO, SecurityCenterTransport + + +class SecurityCenterGrpcTransport(SecurityCenterTransport): + """gRPC backend transport for SecurityCenter. + + V2 APIs for Security Center service. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "securitycenter.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'securitycenter.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the 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 a 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 + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + 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] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + 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: + # 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 + + 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 + + else: + 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 + ) + + # 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, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "securitycenter.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + 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 + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient(self.grpc_channel) + + # Return the client from cache. + return self._operations_client + + @property + def batch_create_resource_value_configs( + self, + ) -> Callable[ + [securitycenter_service.BatchCreateResourceValueConfigsRequest], + securitycenter_service.BatchCreateResourceValueConfigsResponse, + ]: + r"""Return a callable for the batch create resource value + configs method over gRPC. + + Creates a ResourceValueConfig for an organization. + Maps user's tags to difference resource values for use + by the attack path simulation. + + Returns: + Callable[[~.BatchCreateResourceValueConfigsRequest], + ~.BatchCreateResourceValueConfigsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "batch_create_resource_value_configs" not in self._stubs: + self._stubs[ + "batch_create_resource_value_configs" + ] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/BatchCreateResourceValueConfigs", + request_serializer=securitycenter_service.BatchCreateResourceValueConfigsRequest.serialize, + response_deserializer=securitycenter_service.BatchCreateResourceValueConfigsResponse.deserialize, + ) + return self._stubs["batch_create_resource_value_configs"] + + @property + def bulk_mute_findings( + self, + ) -> Callable[ + [securitycenter_service.BulkMuteFindingsRequest], operations_pb2.Operation + ]: + r"""Return a callable for the bulk mute findings method over gRPC. + + Kicks off an LRO to bulk mute findings for a parent + based on a filter. If no location is specified, findings + are muted in global. The parent can be either an + organization, folder, or project. The findings matched + by the filter will be muted after the LRO is done. + + Returns: + Callable[[~.BulkMuteFindingsRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "bulk_mute_findings" not in self._stubs: + self._stubs["bulk_mute_findings"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/BulkMuteFindings", + request_serializer=securitycenter_service.BulkMuteFindingsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["bulk_mute_findings"] + + @property + def create_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.CreateBigQueryExportRequest], + bigquery_export.BigQueryExport, + ]: + r"""Return a callable for the create big query export method over gRPC. + + Creates a BigQuery export. + + Returns: + Callable[[~.CreateBigQueryExportRequest], + ~.BigQueryExport]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_big_query_export" not in self._stubs: + self._stubs["create_big_query_export"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/CreateBigQueryExport", + request_serializer=securitycenter_service.CreateBigQueryExportRequest.serialize, + response_deserializer=bigquery_export.BigQueryExport.deserialize, + ) + return self._stubs["create_big_query_export"] + + @property + def create_finding( + self, + ) -> Callable[[securitycenter_service.CreateFindingRequest], gcs_finding.Finding]: + r"""Return a callable for the create finding method over gRPC. + + Creates a finding in a location. The corresponding + source must exist for finding creation to succeed. + + Returns: + Callable[[~.CreateFindingRequest], + ~.Finding]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_finding" not in self._stubs: + self._stubs["create_finding"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/CreateFinding", + request_serializer=securitycenter_service.CreateFindingRequest.serialize, + response_deserializer=gcs_finding.Finding.deserialize, + ) + return self._stubs["create_finding"] + + @property + def create_mute_config( + self, + ) -> Callable[ + [securitycenter_service.CreateMuteConfigRequest], gcs_mute_config.MuteConfig + ]: + r"""Return a callable for the create mute config method over gRPC. + + Creates a mute config. + + Returns: + Callable[[~.CreateMuteConfigRequest], + ~.MuteConfig]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_mute_config" not in self._stubs: + self._stubs["create_mute_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/CreateMuteConfig", + request_serializer=securitycenter_service.CreateMuteConfigRequest.serialize, + response_deserializer=gcs_mute_config.MuteConfig.deserialize, + ) + return self._stubs["create_mute_config"] + + @property + def create_notification_config( + self, + ) -> Callable[ + [securitycenter_service.CreateNotificationConfigRequest], + gcs_notification_config.NotificationConfig, + ]: + r"""Return a callable for the create notification config method over gRPC. + + Creates a notification config. + + Returns: + Callable[[~.CreateNotificationConfigRequest], + ~.NotificationConfig]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_notification_config" not in self._stubs: + self._stubs["create_notification_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/CreateNotificationConfig", + request_serializer=securitycenter_service.CreateNotificationConfigRequest.serialize, + response_deserializer=gcs_notification_config.NotificationConfig.deserialize, + ) + return self._stubs["create_notification_config"] + + @property + def create_source( + self, + ) -> Callable[[securitycenter_service.CreateSourceRequest], gcs_source.Source]: + r"""Return a callable for the create source method over gRPC. + + Creates a source. + + Returns: + Callable[[~.CreateSourceRequest], + ~.Source]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_source" not in self._stubs: + self._stubs["create_source"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/CreateSource", + request_serializer=securitycenter_service.CreateSourceRequest.serialize, + response_deserializer=gcs_source.Source.deserialize, + ) + return self._stubs["create_source"] + + @property + def delete_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.DeleteBigQueryExportRequest], empty_pb2.Empty + ]: + r"""Return a callable for the delete big query export method over gRPC. + + Deletes an existing BigQuery export. + + Returns: + Callable[[~.DeleteBigQueryExportRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_big_query_export" not in self._stubs: + self._stubs["delete_big_query_export"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/DeleteBigQueryExport", + request_serializer=securitycenter_service.DeleteBigQueryExportRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_big_query_export"] + + @property + def delete_mute_config( + self, + ) -> Callable[[securitycenter_service.DeleteMuteConfigRequest], empty_pb2.Empty]: + r"""Return a callable for the delete mute config method over gRPC. + + Deletes an existing mute config. If no location is + specified, default is global. + + Returns: + Callable[[~.DeleteMuteConfigRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_mute_config" not in self._stubs: + self._stubs["delete_mute_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/DeleteMuteConfig", + request_serializer=securitycenter_service.DeleteMuteConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_mute_config"] + + @property + def delete_notification_config( + self, + ) -> Callable[ + [securitycenter_service.DeleteNotificationConfigRequest], empty_pb2.Empty + ]: + r"""Return a callable for the delete notification config method over gRPC. + + Deletes a notification config. + + Returns: + Callable[[~.DeleteNotificationConfigRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_notification_config" not in self._stubs: + self._stubs["delete_notification_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/DeleteNotificationConfig", + request_serializer=securitycenter_service.DeleteNotificationConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_notification_config"] + + @property + def delete_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.DeleteResourceValueConfigRequest], empty_pb2.Empty + ]: + r"""Return a callable for the delete resource value config method over gRPC. + + Deletes a ResourceValueConfig. + + Returns: + Callable[[~.DeleteResourceValueConfigRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_resource_value_config" not in self._stubs: + self._stubs["delete_resource_value_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/DeleteResourceValueConfig", + request_serializer=securitycenter_service.DeleteResourceValueConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_resource_value_config"] + + @property + def get_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.GetBigQueryExportRequest], + bigquery_export.BigQueryExport, + ]: + r"""Return a callable for the get big query export method over gRPC. + + Gets a BigQuery export. + + Returns: + Callable[[~.GetBigQueryExportRequest], + ~.BigQueryExport]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_big_query_export" not in self._stubs: + self._stubs["get_big_query_export"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetBigQueryExport", + request_serializer=securitycenter_service.GetBigQueryExportRequest.serialize, + response_deserializer=bigquery_export.BigQueryExport.deserialize, + ) + return self._stubs["get_big_query_export"] + + @property + def get_simulation( + self, + ) -> Callable[[securitycenter_service.GetSimulationRequest], simulation.Simulation]: + r"""Return a callable for the get simulation method over gRPC. + + Get the simulation by name or the latest simulation + for the given organization. + + Returns: + Callable[[~.GetSimulationRequest], + ~.Simulation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_simulation" not in self._stubs: + self._stubs["get_simulation"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetSimulation", + request_serializer=securitycenter_service.GetSimulationRequest.serialize, + response_deserializer=simulation.Simulation.deserialize, + ) + return self._stubs["get_simulation"] + + @property + def get_valued_resource( + self, + ) -> Callable[ + [securitycenter_service.GetValuedResourceRequest], + valued_resource.ValuedResource, + ]: + r"""Return a callable for the get valued resource method over gRPC. + + Get the valued resource by name + + Returns: + Callable[[~.GetValuedResourceRequest], + ~.ValuedResource]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_valued_resource" not in self._stubs: + self._stubs["get_valued_resource"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetValuedResource", + request_serializer=securitycenter_service.GetValuedResourceRequest.serialize, + response_deserializer=valued_resource.ValuedResource.deserialize, + ) + return self._stubs["get_valued_resource"] + + @property + def get_iam_policy( + self, + ) -> Callable[[iam_policy_pb2.GetIamPolicyRequest], policy_pb2.Policy]: + r"""Return a callable for the get iam policy method over gRPC. + + Gets the access control policy on the specified + Source. + + Returns: + Callable[[~.GetIamPolicyRequest], + ~.Policy]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_iam_policy" not in self._stubs: + self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetIamPolicy", + request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString, + response_deserializer=policy_pb2.Policy.FromString, + ) + return self._stubs["get_iam_policy"] + + @property + def get_mute_config( + self, + ) -> Callable[ + [securitycenter_service.GetMuteConfigRequest], mute_config.MuteConfig + ]: + r"""Return a callable for the get mute config method over gRPC. + + Gets a mute config. If no location is specified, + default is global. + + Returns: + Callable[[~.GetMuteConfigRequest], + ~.MuteConfig]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_mute_config" not in self._stubs: + self._stubs["get_mute_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetMuteConfig", + request_serializer=securitycenter_service.GetMuteConfigRequest.serialize, + response_deserializer=mute_config.MuteConfig.deserialize, + ) + return self._stubs["get_mute_config"] + + @property + def get_notification_config( + self, + ) -> Callable[ + [securitycenter_service.GetNotificationConfigRequest], + notification_config.NotificationConfig, + ]: + r"""Return a callable for the get notification config method over gRPC. + + Gets a notification config. + + Returns: + Callable[[~.GetNotificationConfigRequest], + ~.NotificationConfig]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_notification_config" not in self._stubs: + self._stubs["get_notification_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetNotificationConfig", + request_serializer=securitycenter_service.GetNotificationConfigRequest.serialize, + response_deserializer=notification_config.NotificationConfig.deserialize, + ) + return self._stubs["get_notification_config"] + + @property + def get_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.GetResourceValueConfigRequest], + resource_value_config.ResourceValueConfig, + ]: + r"""Return a callable for the get resource value config method over gRPC. + + Gets a ResourceValueConfig. + + Returns: + Callable[[~.GetResourceValueConfigRequest], + ~.ResourceValueConfig]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_resource_value_config" not in self._stubs: + self._stubs["get_resource_value_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetResourceValueConfig", + request_serializer=securitycenter_service.GetResourceValueConfigRequest.serialize, + response_deserializer=resource_value_config.ResourceValueConfig.deserialize, + ) + return self._stubs["get_resource_value_config"] + + @property + def get_source( + self, + ) -> Callable[[securitycenter_service.GetSourceRequest], source.Source]: + r"""Return a callable for the get source method over gRPC. + + Gets a source. + + Returns: + Callable[[~.GetSourceRequest], + ~.Source]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_source" not in self._stubs: + self._stubs["get_source"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetSource", + request_serializer=securitycenter_service.GetSourceRequest.serialize, + response_deserializer=source.Source.deserialize, + ) + return self._stubs["get_source"] + + @property + def group_findings( + self, + ) -> Callable[ + [securitycenter_service.GroupFindingsRequest], + securitycenter_service.GroupFindingsResponse, + ]: + r"""Return a callable for the group findings method over gRPC. + + Filters an organization or source's findings and groups them by + their specified properties in a location. If no location is + specified, findings are assumed to be in global + + To group across all sources provide a ``-`` as the source id. + The following list shows some examples: + + - ``/v2/organizations/{organization_id}/sources/-/findings`` + - + + ``/v2/organizations/{organization_id}/sources/-/locations/{location_id}/findings`` + + - ``/v2/folders/{folder_id}/sources/-/findings`` + - ``/v2/folders/{folder_id}/sources/-/locations/{location_id}/findings`` + - ``/v2/projects/{project_id}/sources/-/findings`` + - ``/v2/projects/{project_id}/sources/-/locations/{location_id}/findings`` + + Returns: + Callable[[~.GroupFindingsRequest], + ~.GroupFindingsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "group_findings" not in self._stubs: + self._stubs["group_findings"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GroupFindings", + request_serializer=securitycenter_service.GroupFindingsRequest.serialize, + response_deserializer=securitycenter_service.GroupFindingsResponse.deserialize, + ) + return self._stubs["group_findings"] + + @property + def list_attack_paths( + self, + ) -> Callable[ + [securitycenter_service.ListAttackPathsRequest], + securitycenter_service.ListAttackPathsResponse, + ]: + r"""Return a callable for the list attack paths method over gRPC. + + Lists the attack paths for a set of simulation + results or valued resources and filter. + + Returns: + Callable[[~.ListAttackPathsRequest], + ~.ListAttackPathsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_attack_paths" not in self._stubs: + self._stubs["list_attack_paths"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListAttackPaths", + request_serializer=securitycenter_service.ListAttackPathsRequest.serialize, + response_deserializer=securitycenter_service.ListAttackPathsResponse.deserialize, + ) + return self._stubs["list_attack_paths"] + + @property + def list_big_query_exports( + self, + ) -> Callable[ + [securitycenter_service.ListBigQueryExportsRequest], + securitycenter_service.ListBigQueryExportsResponse, + ]: + r"""Return a callable for the list big query exports method over gRPC. + + Lists BigQuery exports. Note that when requesting + BigQuery exports at a given level all exports under that + level are also returned e.g. if requesting BigQuery + exports under a folder, then all BigQuery exports + immediately under the folder plus the ones created under + the projects within the folder are returned. + + Returns: + Callable[[~.ListBigQueryExportsRequest], + ~.ListBigQueryExportsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_big_query_exports" not in self._stubs: + self._stubs["list_big_query_exports"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListBigQueryExports", + request_serializer=securitycenter_service.ListBigQueryExportsRequest.serialize, + response_deserializer=securitycenter_service.ListBigQueryExportsResponse.deserialize, + ) + return self._stubs["list_big_query_exports"] + + @property + def list_findings( + self, + ) -> Callable[ + [securitycenter_service.ListFindingsRequest], + securitycenter_service.ListFindingsResponse, + ]: + r"""Return a callable for the list findings method over gRPC. + + Lists an organization or source's findings. + + To list across all sources for a given location provide a ``-`` + as the source id. If no location is specified, finding are + assumed to be in global. The following list shows some examples: + + - ``/v2/organizations/{organization_id}/sources/-/findings`` + - + + ``/v2/organizations/{organization_id}/sources/-/locations/{location_id}/findings`` + + Returns: + Callable[[~.ListFindingsRequest], + ~.ListFindingsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_findings" not in self._stubs: + self._stubs["list_findings"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListFindings", + request_serializer=securitycenter_service.ListFindingsRequest.serialize, + response_deserializer=securitycenter_service.ListFindingsResponse.deserialize, + ) + return self._stubs["list_findings"] + + @property + def list_mute_configs( + self, + ) -> Callable[ + [securitycenter_service.ListMuteConfigsRequest], + securitycenter_service.ListMuteConfigsResponse, + ]: + r"""Return a callable for the list mute configs method over gRPC. + + Lists mute configs. If no location is specified, + default is global. + + Returns: + Callable[[~.ListMuteConfigsRequest], + ~.ListMuteConfigsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_mute_configs" not in self._stubs: + self._stubs["list_mute_configs"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListMuteConfigs", + request_serializer=securitycenter_service.ListMuteConfigsRequest.serialize, + response_deserializer=securitycenter_service.ListMuteConfigsResponse.deserialize, + ) + return self._stubs["list_mute_configs"] + + @property + def list_notification_configs( + self, + ) -> Callable[ + [securitycenter_service.ListNotificationConfigsRequest], + securitycenter_service.ListNotificationConfigsResponse, + ]: + r"""Return a callable for the list notification configs method over gRPC. + + Lists notification configs. + + Returns: + Callable[[~.ListNotificationConfigsRequest], + ~.ListNotificationConfigsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_notification_configs" not in self._stubs: + self._stubs["list_notification_configs"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListNotificationConfigs", + request_serializer=securitycenter_service.ListNotificationConfigsRequest.serialize, + response_deserializer=securitycenter_service.ListNotificationConfigsResponse.deserialize, + ) + return self._stubs["list_notification_configs"] + + @property + def list_resource_value_configs( + self, + ) -> Callable[ + [securitycenter_service.ListResourceValueConfigsRequest], + securitycenter_service.ListResourceValueConfigsResponse, + ]: + r"""Return a callable for the list resource value configs method over gRPC. + + Lists all ResourceValueConfigs. + + Returns: + Callable[[~.ListResourceValueConfigsRequest], + ~.ListResourceValueConfigsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_resource_value_configs" not in self._stubs: + self._stubs["list_resource_value_configs"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListResourceValueConfigs", + request_serializer=securitycenter_service.ListResourceValueConfigsRequest.serialize, + response_deserializer=securitycenter_service.ListResourceValueConfigsResponse.deserialize, + ) + return self._stubs["list_resource_value_configs"] + + @property + def list_sources( + self, + ) -> Callable[ + [securitycenter_service.ListSourcesRequest], + securitycenter_service.ListSourcesResponse, + ]: + r"""Return a callable for the list sources method over gRPC. + + Lists all sources belonging to an organization. + + Returns: + Callable[[~.ListSourcesRequest], + ~.ListSourcesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_sources" not in self._stubs: + self._stubs["list_sources"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListSources", + request_serializer=securitycenter_service.ListSourcesRequest.serialize, + response_deserializer=securitycenter_service.ListSourcesResponse.deserialize, + ) + return self._stubs["list_sources"] + + @property + def list_valued_resources( + self, + ) -> Callable[ + [securitycenter_service.ListValuedResourcesRequest], + securitycenter_service.ListValuedResourcesResponse, + ]: + r"""Return a callable for the list valued resources method over gRPC. + + Lists the valued resources for a set of simulation + results and filter. + + Returns: + Callable[[~.ListValuedResourcesRequest], + ~.ListValuedResourcesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_valued_resources" not in self._stubs: + self._stubs["list_valued_resources"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListValuedResources", + request_serializer=securitycenter_service.ListValuedResourcesRequest.serialize, + response_deserializer=securitycenter_service.ListValuedResourcesResponse.deserialize, + ) + return self._stubs["list_valued_resources"] + + @property + def set_finding_state( + self, + ) -> Callable[[securitycenter_service.SetFindingStateRequest], finding.Finding]: + r"""Return a callable for the set finding state method over gRPC. + + Updates the state of a finding. If no location is + specified, finding is assumed to be in global + + Returns: + Callable[[~.SetFindingStateRequest], + ~.Finding]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "set_finding_state" not in self._stubs: + self._stubs["set_finding_state"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/SetFindingState", + request_serializer=securitycenter_service.SetFindingStateRequest.serialize, + response_deserializer=finding.Finding.deserialize, + ) + return self._stubs["set_finding_state"] + + @property + def set_iam_policy( + self, + ) -> Callable[[iam_policy_pb2.SetIamPolicyRequest], policy_pb2.Policy]: + r"""Return a callable for the set iam policy method over gRPC. + + Sets the access control policy on the specified + Source. + + Returns: + Callable[[~.SetIamPolicyRequest], + ~.Policy]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "set_iam_policy" not in self._stubs: + self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/SetIamPolicy", + request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString, + response_deserializer=policy_pb2.Policy.FromString, + ) + return self._stubs["set_iam_policy"] + + @property + def set_mute( + self, + ) -> Callable[[securitycenter_service.SetMuteRequest], finding.Finding]: + r"""Return a callable for the set mute method over gRPC. + + Updates the mute state of a finding. If no location + is specified, finding is assumed to be in global + + Returns: + Callable[[~.SetMuteRequest], + ~.Finding]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "set_mute" not in self._stubs: + self._stubs["set_mute"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/SetMute", + request_serializer=securitycenter_service.SetMuteRequest.serialize, + response_deserializer=finding.Finding.deserialize, + ) + return self._stubs["set_mute"] + + @property + def test_iam_permissions( + self, + ) -> Callable[ + [iam_policy_pb2.TestIamPermissionsRequest], + iam_policy_pb2.TestIamPermissionsResponse, + ]: + r"""Return a callable for the test iam permissions method over gRPC. + + Returns the permissions that a caller has on the + specified source. + + Returns: + Callable[[~.TestIamPermissionsRequest], + ~.TestIamPermissionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "test_iam_permissions" not in self._stubs: + self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/TestIamPermissions", + request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString, + response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString, + ) + return self._stubs["test_iam_permissions"] + + @property + def update_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.UpdateBigQueryExportRequest], + bigquery_export.BigQueryExport, + ]: + r"""Return a callable for the update big query export method over gRPC. + + Updates a BigQuery export. + + Returns: + Callable[[~.UpdateBigQueryExportRequest], + ~.BigQueryExport]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_big_query_export" not in self._stubs: + self._stubs["update_big_query_export"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateBigQueryExport", + request_serializer=securitycenter_service.UpdateBigQueryExportRequest.serialize, + response_deserializer=bigquery_export.BigQueryExport.deserialize, + ) + return self._stubs["update_big_query_export"] + + @property + def update_external_system( + self, + ) -> Callable[ + [securitycenter_service.UpdateExternalSystemRequest], + gcs_external_system.ExternalSystem, + ]: + r"""Return a callable for the update external system method over gRPC. + + Updates external system. This is for a given finding. + If no location is specified, finding is assumed to be in + global + + Returns: + Callable[[~.UpdateExternalSystemRequest], + ~.ExternalSystem]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_external_system" not in self._stubs: + self._stubs["update_external_system"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateExternalSystem", + request_serializer=securitycenter_service.UpdateExternalSystemRequest.serialize, + response_deserializer=gcs_external_system.ExternalSystem.deserialize, + ) + return self._stubs["update_external_system"] + + @property + def update_finding( + self, + ) -> Callable[[securitycenter_service.UpdateFindingRequest], gcs_finding.Finding]: + r"""Return a callable for the update finding method over gRPC. + + Creates or updates a finding. If no location is + specified, finding is assumed to be in global. The + corresponding source must exist for a finding creation + to succeed. + + Returns: + Callable[[~.UpdateFindingRequest], + ~.Finding]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_finding" not in self._stubs: + self._stubs["update_finding"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateFinding", + request_serializer=securitycenter_service.UpdateFindingRequest.serialize, + response_deserializer=gcs_finding.Finding.deserialize, + ) + return self._stubs["update_finding"] + + @property + def update_mute_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateMuteConfigRequest], gcs_mute_config.MuteConfig + ]: + r"""Return a callable for the update mute config method over gRPC. + + Updates a mute config. If no location is specified, + default is global. + + Returns: + Callable[[~.UpdateMuteConfigRequest], + ~.MuteConfig]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_mute_config" not in self._stubs: + self._stubs["update_mute_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateMuteConfig", + request_serializer=securitycenter_service.UpdateMuteConfigRequest.serialize, + response_deserializer=gcs_mute_config.MuteConfig.deserialize, + ) + return self._stubs["update_mute_config"] + + @property + def update_notification_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateNotificationConfigRequest], + gcs_notification_config.NotificationConfig, + ]: + r"""Return a callable for the update notification config method over gRPC. + + Updates a notification config. The following update fields are + allowed: description, pubsub_topic, streaming_config.filter + + Returns: + Callable[[~.UpdateNotificationConfigRequest], + ~.NotificationConfig]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_notification_config" not in self._stubs: + self._stubs["update_notification_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateNotificationConfig", + request_serializer=securitycenter_service.UpdateNotificationConfigRequest.serialize, + response_deserializer=gcs_notification_config.NotificationConfig.deserialize, + ) + return self._stubs["update_notification_config"] + + @property + def update_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateResourceValueConfigRequest], + gcs_resource_value_config.ResourceValueConfig, + ]: + r"""Return a callable for the update resource value config method over gRPC. + + Updates an existing ResourceValueConfigs with new + rules. + + Returns: + Callable[[~.UpdateResourceValueConfigRequest], + ~.ResourceValueConfig]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_resource_value_config" not in self._stubs: + self._stubs["update_resource_value_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateResourceValueConfig", + request_serializer=securitycenter_service.UpdateResourceValueConfigRequest.serialize, + response_deserializer=gcs_resource_value_config.ResourceValueConfig.deserialize, + ) + return self._stubs["update_resource_value_config"] + + @property + def update_security_marks( + self, + ) -> Callable[ + [securitycenter_service.UpdateSecurityMarksRequest], + gcs_security_marks.SecurityMarks, + ]: + r"""Return a callable for the update security marks method over gRPC. + + Updates security marks. For Finding Security marks, + if no location is specified, finding is assumed to be in + global. Assets Security Marks can only be accessed + through global endpoint. + + Returns: + Callable[[~.UpdateSecurityMarksRequest], + ~.SecurityMarks]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_security_marks" not in self._stubs: + self._stubs["update_security_marks"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateSecurityMarks", + request_serializer=securitycenter_service.UpdateSecurityMarksRequest.serialize, + response_deserializer=gcs_security_marks.SecurityMarks.deserialize, + ) + return self._stubs["update_security_marks"] + + @property + def update_source( + self, + ) -> Callable[[securitycenter_service.UpdateSourceRequest], gcs_source.Source]: + r"""Return a callable for the update source method over gRPC. + + Updates a source. + + Returns: + Callable[[~.UpdateSourceRequest], + ~.Source]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_source" not in self._stubs: + self._stubs["update_source"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateSource", + request_serializer=securitycenter_service.UpdateSourceRequest.serialize, + response_deserializer=gcs_source.Source.deserialize, + ) + return self._stubs["update_source"] + + def close(self): + self.grpc_channel.close() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("SecurityCenterGrpcTransport",) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/grpc_asyncio.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/grpc_asyncio.py new file mode 100644 index 000000000000..49f609f503b3 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/grpc_asyncio.py @@ -0,0 +1,1547 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.iam.v1 import iam_policy_pb2 # type: ignore +from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.securitycenter_v2.types import securitycenter_service, simulation +from google.cloud.securitycenter_v2.types import external_system as gcs_external_system +from google.cloud.securitycenter_v2.types import ( + notification_config as gcs_notification_config, +) +from google.cloud.securitycenter_v2.types import ( + resource_value_config as gcs_resource_value_config, +) +from google.cloud.securitycenter_v2.types import security_marks as gcs_security_marks +from google.cloud.securitycenter_v2.types import bigquery_export +from google.cloud.securitycenter_v2.types import finding +from google.cloud.securitycenter_v2.types import finding as gcs_finding +from google.cloud.securitycenter_v2.types import mute_config +from google.cloud.securitycenter_v2.types import mute_config as gcs_mute_config +from google.cloud.securitycenter_v2.types import notification_config +from google.cloud.securitycenter_v2.types import resource_value_config +from google.cloud.securitycenter_v2.types import source +from google.cloud.securitycenter_v2.types import source as gcs_source +from google.cloud.securitycenter_v2.types import valued_resource + +from .base import DEFAULT_CLIENT_INFO, SecurityCenterTransport +from .grpc import SecurityCenterGrpcTransport + + +class SecurityCenterGrpcAsyncIOTransport(SecurityCenterTransport): + """gRPC AsyncIO backend transport for SecurityCenter. + + V2 APIs for Security Center service. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "securitycenter.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + 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 + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "securitycenter.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'securitycenter.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the 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 a 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 + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + 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] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + 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: + # 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 + 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 + + else: + 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 + ) + + # 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, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def batch_create_resource_value_configs( + self, + ) -> Callable[ + [securitycenter_service.BatchCreateResourceValueConfigsRequest], + Awaitable[securitycenter_service.BatchCreateResourceValueConfigsResponse], + ]: + r"""Return a callable for the batch create resource value + configs method over gRPC. + + Creates a ResourceValueConfig for an organization. + Maps user's tags to difference resource values for use + by the attack path simulation. + + Returns: + Callable[[~.BatchCreateResourceValueConfigsRequest], + Awaitable[~.BatchCreateResourceValueConfigsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "batch_create_resource_value_configs" not in self._stubs: + self._stubs[ + "batch_create_resource_value_configs" + ] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/BatchCreateResourceValueConfigs", + request_serializer=securitycenter_service.BatchCreateResourceValueConfigsRequest.serialize, + response_deserializer=securitycenter_service.BatchCreateResourceValueConfigsResponse.deserialize, + ) + return self._stubs["batch_create_resource_value_configs"] + + @property + def bulk_mute_findings( + self, + ) -> Callable[ + [securitycenter_service.BulkMuteFindingsRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the bulk mute findings method over gRPC. + + Kicks off an LRO to bulk mute findings for a parent + based on a filter. If no location is specified, findings + are muted in global. The parent can be either an + organization, folder, or project. The findings matched + by the filter will be muted after the LRO is done. + + Returns: + Callable[[~.BulkMuteFindingsRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "bulk_mute_findings" not in self._stubs: + self._stubs["bulk_mute_findings"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/BulkMuteFindings", + request_serializer=securitycenter_service.BulkMuteFindingsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["bulk_mute_findings"] + + @property + def create_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.CreateBigQueryExportRequest], + Awaitable[bigquery_export.BigQueryExport], + ]: + r"""Return a callable for the create big query export method over gRPC. + + Creates a BigQuery export. + + Returns: + Callable[[~.CreateBigQueryExportRequest], + Awaitable[~.BigQueryExport]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_big_query_export" not in self._stubs: + self._stubs["create_big_query_export"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/CreateBigQueryExport", + request_serializer=securitycenter_service.CreateBigQueryExportRequest.serialize, + response_deserializer=bigquery_export.BigQueryExport.deserialize, + ) + return self._stubs["create_big_query_export"] + + @property + def create_finding( + self, + ) -> Callable[ + [securitycenter_service.CreateFindingRequest], Awaitable[gcs_finding.Finding] + ]: + r"""Return a callable for the create finding method over gRPC. + + Creates a finding in a location. The corresponding + source must exist for finding creation to succeed. + + Returns: + Callable[[~.CreateFindingRequest], + Awaitable[~.Finding]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_finding" not in self._stubs: + self._stubs["create_finding"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/CreateFinding", + request_serializer=securitycenter_service.CreateFindingRequest.serialize, + response_deserializer=gcs_finding.Finding.deserialize, + ) + return self._stubs["create_finding"] + + @property + def create_mute_config( + self, + ) -> Callable[ + [securitycenter_service.CreateMuteConfigRequest], + Awaitable[gcs_mute_config.MuteConfig], + ]: + r"""Return a callable for the create mute config method over gRPC. + + Creates a mute config. + + Returns: + Callable[[~.CreateMuteConfigRequest], + Awaitable[~.MuteConfig]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_mute_config" not in self._stubs: + self._stubs["create_mute_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/CreateMuteConfig", + request_serializer=securitycenter_service.CreateMuteConfigRequest.serialize, + response_deserializer=gcs_mute_config.MuteConfig.deserialize, + ) + return self._stubs["create_mute_config"] + + @property + def create_notification_config( + self, + ) -> Callable[ + [securitycenter_service.CreateNotificationConfigRequest], + Awaitable[gcs_notification_config.NotificationConfig], + ]: + r"""Return a callable for the create notification config method over gRPC. + + Creates a notification config. + + Returns: + Callable[[~.CreateNotificationConfigRequest], + Awaitable[~.NotificationConfig]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_notification_config" not in self._stubs: + self._stubs["create_notification_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/CreateNotificationConfig", + request_serializer=securitycenter_service.CreateNotificationConfigRequest.serialize, + response_deserializer=gcs_notification_config.NotificationConfig.deserialize, + ) + return self._stubs["create_notification_config"] + + @property + def create_source( + self, + ) -> Callable[ + [securitycenter_service.CreateSourceRequest], Awaitable[gcs_source.Source] + ]: + r"""Return a callable for the create source method over gRPC. + + Creates a source. + + Returns: + Callable[[~.CreateSourceRequest], + Awaitable[~.Source]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_source" not in self._stubs: + self._stubs["create_source"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/CreateSource", + request_serializer=securitycenter_service.CreateSourceRequest.serialize, + response_deserializer=gcs_source.Source.deserialize, + ) + return self._stubs["create_source"] + + @property + def delete_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.DeleteBigQueryExportRequest], Awaitable[empty_pb2.Empty] + ]: + r"""Return a callable for the delete big query export method over gRPC. + + Deletes an existing BigQuery export. + + Returns: + Callable[[~.DeleteBigQueryExportRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_big_query_export" not in self._stubs: + self._stubs["delete_big_query_export"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/DeleteBigQueryExport", + request_serializer=securitycenter_service.DeleteBigQueryExportRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_big_query_export"] + + @property + def delete_mute_config( + self, + ) -> Callable[ + [securitycenter_service.DeleteMuteConfigRequest], Awaitable[empty_pb2.Empty] + ]: + r"""Return a callable for the delete mute config method over gRPC. + + Deletes an existing mute config. If no location is + specified, default is global. + + Returns: + Callable[[~.DeleteMuteConfigRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_mute_config" not in self._stubs: + self._stubs["delete_mute_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/DeleteMuteConfig", + request_serializer=securitycenter_service.DeleteMuteConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_mute_config"] + + @property + def delete_notification_config( + self, + ) -> Callable[ + [securitycenter_service.DeleteNotificationConfigRequest], + Awaitable[empty_pb2.Empty], + ]: + r"""Return a callable for the delete notification config method over gRPC. + + Deletes a notification config. + + Returns: + Callable[[~.DeleteNotificationConfigRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_notification_config" not in self._stubs: + self._stubs["delete_notification_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/DeleteNotificationConfig", + request_serializer=securitycenter_service.DeleteNotificationConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_notification_config"] + + @property + def delete_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.DeleteResourceValueConfigRequest], + Awaitable[empty_pb2.Empty], + ]: + r"""Return a callable for the delete resource value config method over gRPC. + + Deletes a ResourceValueConfig. + + Returns: + Callable[[~.DeleteResourceValueConfigRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_resource_value_config" not in self._stubs: + self._stubs["delete_resource_value_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/DeleteResourceValueConfig", + request_serializer=securitycenter_service.DeleteResourceValueConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_resource_value_config"] + + @property + def get_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.GetBigQueryExportRequest], + Awaitable[bigquery_export.BigQueryExport], + ]: + r"""Return a callable for the get big query export method over gRPC. + + Gets a BigQuery export. + + Returns: + Callable[[~.GetBigQueryExportRequest], + Awaitable[~.BigQueryExport]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_big_query_export" not in self._stubs: + self._stubs["get_big_query_export"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetBigQueryExport", + request_serializer=securitycenter_service.GetBigQueryExportRequest.serialize, + response_deserializer=bigquery_export.BigQueryExport.deserialize, + ) + return self._stubs["get_big_query_export"] + + @property + def get_simulation( + self, + ) -> Callable[ + [securitycenter_service.GetSimulationRequest], Awaitable[simulation.Simulation] + ]: + r"""Return a callable for the get simulation method over gRPC. + + Get the simulation by name or the latest simulation + for the given organization. + + Returns: + Callable[[~.GetSimulationRequest], + Awaitable[~.Simulation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_simulation" not in self._stubs: + self._stubs["get_simulation"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetSimulation", + request_serializer=securitycenter_service.GetSimulationRequest.serialize, + response_deserializer=simulation.Simulation.deserialize, + ) + return self._stubs["get_simulation"] + + @property + def get_valued_resource( + self, + ) -> Callable[ + [securitycenter_service.GetValuedResourceRequest], + Awaitable[valued_resource.ValuedResource], + ]: + r"""Return a callable for the get valued resource method over gRPC. + + Get the valued resource by name + + Returns: + Callable[[~.GetValuedResourceRequest], + Awaitable[~.ValuedResource]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_valued_resource" not in self._stubs: + self._stubs["get_valued_resource"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetValuedResource", + request_serializer=securitycenter_service.GetValuedResourceRequest.serialize, + response_deserializer=valued_resource.ValuedResource.deserialize, + ) + return self._stubs["get_valued_resource"] + + @property + def get_iam_policy( + self, + ) -> Callable[[iam_policy_pb2.GetIamPolicyRequest], Awaitable[policy_pb2.Policy]]: + r"""Return a callable for the get iam policy method over gRPC. + + Gets the access control policy on the specified + Source. + + Returns: + Callable[[~.GetIamPolicyRequest], + Awaitable[~.Policy]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_iam_policy" not in self._stubs: + self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetIamPolicy", + request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString, + response_deserializer=policy_pb2.Policy.FromString, + ) + return self._stubs["get_iam_policy"] + + @property + def get_mute_config( + self, + ) -> Callable[ + [securitycenter_service.GetMuteConfigRequest], Awaitable[mute_config.MuteConfig] + ]: + r"""Return a callable for the get mute config method over gRPC. + + Gets a mute config. If no location is specified, + default is global. + + Returns: + Callable[[~.GetMuteConfigRequest], + Awaitable[~.MuteConfig]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_mute_config" not in self._stubs: + self._stubs["get_mute_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetMuteConfig", + request_serializer=securitycenter_service.GetMuteConfigRequest.serialize, + response_deserializer=mute_config.MuteConfig.deserialize, + ) + return self._stubs["get_mute_config"] + + @property + def get_notification_config( + self, + ) -> Callable[ + [securitycenter_service.GetNotificationConfigRequest], + Awaitable[notification_config.NotificationConfig], + ]: + r"""Return a callable for the get notification config method over gRPC. + + Gets a notification config. + + Returns: + Callable[[~.GetNotificationConfigRequest], + Awaitable[~.NotificationConfig]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_notification_config" not in self._stubs: + self._stubs["get_notification_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetNotificationConfig", + request_serializer=securitycenter_service.GetNotificationConfigRequest.serialize, + response_deserializer=notification_config.NotificationConfig.deserialize, + ) + return self._stubs["get_notification_config"] + + @property + def get_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.GetResourceValueConfigRequest], + Awaitable[resource_value_config.ResourceValueConfig], + ]: + r"""Return a callable for the get resource value config method over gRPC. + + Gets a ResourceValueConfig. + + Returns: + Callable[[~.GetResourceValueConfigRequest], + Awaitable[~.ResourceValueConfig]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_resource_value_config" not in self._stubs: + self._stubs["get_resource_value_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetResourceValueConfig", + request_serializer=securitycenter_service.GetResourceValueConfigRequest.serialize, + response_deserializer=resource_value_config.ResourceValueConfig.deserialize, + ) + return self._stubs["get_resource_value_config"] + + @property + def get_source( + self, + ) -> Callable[[securitycenter_service.GetSourceRequest], Awaitable[source.Source]]: + r"""Return a callable for the get source method over gRPC. + + Gets a source. + + Returns: + Callable[[~.GetSourceRequest], + Awaitable[~.Source]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_source" not in self._stubs: + self._stubs["get_source"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GetSource", + request_serializer=securitycenter_service.GetSourceRequest.serialize, + response_deserializer=source.Source.deserialize, + ) + return self._stubs["get_source"] + + @property + def group_findings( + self, + ) -> Callable[ + [securitycenter_service.GroupFindingsRequest], + Awaitable[securitycenter_service.GroupFindingsResponse], + ]: + r"""Return a callable for the group findings method over gRPC. + + Filters an organization or source's findings and groups them by + their specified properties in a location. If no location is + specified, findings are assumed to be in global + + To group across all sources provide a ``-`` as the source id. + The following list shows some examples: + + - ``/v2/organizations/{organization_id}/sources/-/findings`` + - + + ``/v2/organizations/{organization_id}/sources/-/locations/{location_id}/findings`` + + - ``/v2/folders/{folder_id}/sources/-/findings`` + - ``/v2/folders/{folder_id}/sources/-/locations/{location_id}/findings`` + - ``/v2/projects/{project_id}/sources/-/findings`` + - ``/v2/projects/{project_id}/sources/-/locations/{location_id}/findings`` + + Returns: + Callable[[~.GroupFindingsRequest], + Awaitable[~.GroupFindingsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "group_findings" not in self._stubs: + self._stubs["group_findings"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/GroupFindings", + request_serializer=securitycenter_service.GroupFindingsRequest.serialize, + response_deserializer=securitycenter_service.GroupFindingsResponse.deserialize, + ) + return self._stubs["group_findings"] + + @property + def list_attack_paths( + self, + ) -> Callable[ + [securitycenter_service.ListAttackPathsRequest], + Awaitable[securitycenter_service.ListAttackPathsResponse], + ]: + r"""Return a callable for the list attack paths method over gRPC. + + Lists the attack paths for a set of simulation + results or valued resources and filter. + + Returns: + Callable[[~.ListAttackPathsRequest], + Awaitable[~.ListAttackPathsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_attack_paths" not in self._stubs: + self._stubs["list_attack_paths"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListAttackPaths", + request_serializer=securitycenter_service.ListAttackPathsRequest.serialize, + response_deserializer=securitycenter_service.ListAttackPathsResponse.deserialize, + ) + return self._stubs["list_attack_paths"] + + @property + def list_big_query_exports( + self, + ) -> Callable[ + [securitycenter_service.ListBigQueryExportsRequest], + Awaitable[securitycenter_service.ListBigQueryExportsResponse], + ]: + r"""Return a callable for the list big query exports method over gRPC. + + Lists BigQuery exports. Note that when requesting + BigQuery exports at a given level all exports under that + level are also returned e.g. if requesting BigQuery + exports under a folder, then all BigQuery exports + immediately under the folder plus the ones created under + the projects within the folder are returned. + + Returns: + Callable[[~.ListBigQueryExportsRequest], + Awaitable[~.ListBigQueryExportsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_big_query_exports" not in self._stubs: + self._stubs["list_big_query_exports"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListBigQueryExports", + request_serializer=securitycenter_service.ListBigQueryExportsRequest.serialize, + response_deserializer=securitycenter_service.ListBigQueryExportsResponse.deserialize, + ) + return self._stubs["list_big_query_exports"] + + @property + def list_findings( + self, + ) -> Callable[ + [securitycenter_service.ListFindingsRequest], + Awaitable[securitycenter_service.ListFindingsResponse], + ]: + r"""Return a callable for the list findings method over gRPC. + + Lists an organization or source's findings. + + To list across all sources for a given location provide a ``-`` + as the source id. If no location is specified, finding are + assumed to be in global. The following list shows some examples: + + - ``/v2/organizations/{organization_id}/sources/-/findings`` + - + + ``/v2/organizations/{organization_id}/sources/-/locations/{location_id}/findings`` + + Returns: + Callable[[~.ListFindingsRequest], + Awaitable[~.ListFindingsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_findings" not in self._stubs: + self._stubs["list_findings"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListFindings", + request_serializer=securitycenter_service.ListFindingsRequest.serialize, + response_deserializer=securitycenter_service.ListFindingsResponse.deserialize, + ) + return self._stubs["list_findings"] + + @property + def list_mute_configs( + self, + ) -> Callable[ + [securitycenter_service.ListMuteConfigsRequest], + Awaitable[securitycenter_service.ListMuteConfigsResponse], + ]: + r"""Return a callable for the list mute configs method over gRPC. + + Lists mute configs. If no location is specified, + default is global. + + Returns: + Callable[[~.ListMuteConfigsRequest], + Awaitable[~.ListMuteConfigsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_mute_configs" not in self._stubs: + self._stubs["list_mute_configs"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListMuteConfigs", + request_serializer=securitycenter_service.ListMuteConfigsRequest.serialize, + response_deserializer=securitycenter_service.ListMuteConfigsResponse.deserialize, + ) + return self._stubs["list_mute_configs"] + + @property + def list_notification_configs( + self, + ) -> Callable[ + [securitycenter_service.ListNotificationConfigsRequest], + Awaitable[securitycenter_service.ListNotificationConfigsResponse], + ]: + r"""Return a callable for the list notification configs method over gRPC. + + Lists notification configs. + + Returns: + Callable[[~.ListNotificationConfigsRequest], + Awaitable[~.ListNotificationConfigsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_notification_configs" not in self._stubs: + self._stubs["list_notification_configs"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListNotificationConfigs", + request_serializer=securitycenter_service.ListNotificationConfigsRequest.serialize, + response_deserializer=securitycenter_service.ListNotificationConfigsResponse.deserialize, + ) + return self._stubs["list_notification_configs"] + + @property + def list_resource_value_configs( + self, + ) -> Callable[ + [securitycenter_service.ListResourceValueConfigsRequest], + Awaitable[securitycenter_service.ListResourceValueConfigsResponse], + ]: + r"""Return a callable for the list resource value configs method over gRPC. + + Lists all ResourceValueConfigs. + + Returns: + Callable[[~.ListResourceValueConfigsRequest], + Awaitable[~.ListResourceValueConfigsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_resource_value_configs" not in self._stubs: + self._stubs["list_resource_value_configs"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListResourceValueConfigs", + request_serializer=securitycenter_service.ListResourceValueConfigsRequest.serialize, + response_deserializer=securitycenter_service.ListResourceValueConfigsResponse.deserialize, + ) + return self._stubs["list_resource_value_configs"] + + @property + def list_sources( + self, + ) -> Callable[ + [securitycenter_service.ListSourcesRequest], + Awaitable[securitycenter_service.ListSourcesResponse], + ]: + r"""Return a callable for the list sources method over gRPC. + + Lists all sources belonging to an organization. + + Returns: + Callable[[~.ListSourcesRequest], + Awaitable[~.ListSourcesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_sources" not in self._stubs: + self._stubs["list_sources"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListSources", + request_serializer=securitycenter_service.ListSourcesRequest.serialize, + response_deserializer=securitycenter_service.ListSourcesResponse.deserialize, + ) + return self._stubs["list_sources"] + + @property + def list_valued_resources( + self, + ) -> Callable[ + [securitycenter_service.ListValuedResourcesRequest], + Awaitable[securitycenter_service.ListValuedResourcesResponse], + ]: + r"""Return a callable for the list valued resources method over gRPC. + + Lists the valued resources for a set of simulation + results and filter. + + Returns: + Callable[[~.ListValuedResourcesRequest], + Awaitable[~.ListValuedResourcesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_valued_resources" not in self._stubs: + self._stubs["list_valued_resources"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/ListValuedResources", + request_serializer=securitycenter_service.ListValuedResourcesRequest.serialize, + response_deserializer=securitycenter_service.ListValuedResourcesResponse.deserialize, + ) + return self._stubs["list_valued_resources"] + + @property + def set_finding_state( + self, + ) -> Callable[ + [securitycenter_service.SetFindingStateRequest], Awaitable[finding.Finding] + ]: + r"""Return a callable for the set finding state method over gRPC. + + Updates the state of a finding. If no location is + specified, finding is assumed to be in global + + Returns: + Callable[[~.SetFindingStateRequest], + Awaitable[~.Finding]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "set_finding_state" not in self._stubs: + self._stubs["set_finding_state"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/SetFindingState", + request_serializer=securitycenter_service.SetFindingStateRequest.serialize, + response_deserializer=finding.Finding.deserialize, + ) + return self._stubs["set_finding_state"] + + @property + def set_iam_policy( + self, + ) -> Callable[[iam_policy_pb2.SetIamPolicyRequest], Awaitable[policy_pb2.Policy]]: + r"""Return a callable for the set iam policy method over gRPC. + + Sets the access control policy on the specified + Source. + + Returns: + Callable[[~.SetIamPolicyRequest], + Awaitable[~.Policy]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "set_iam_policy" not in self._stubs: + self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/SetIamPolicy", + request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString, + response_deserializer=policy_pb2.Policy.FromString, + ) + return self._stubs["set_iam_policy"] + + @property + def set_mute( + self, + ) -> Callable[[securitycenter_service.SetMuteRequest], Awaitable[finding.Finding]]: + r"""Return a callable for the set mute method over gRPC. + + Updates the mute state of a finding. If no location + is specified, finding is assumed to be in global + + Returns: + Callable[[~.SetMuteRequest], + Awaitable[~.Finding]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "set_mute" not in self._stubs: + self._stubs["set_mute"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/SetMute", + request_serializer=securitycenter_service.SetMuteRequest.serialize, + response_deserializer=finding.Finding.deserialize, + ) + return self._stubs["set_mute"] + + @property + def test_iam_permissions( + self, + ) -> Callable[ + [iam_policy_pb2.TestIamPermissionsRequest], + Awaitable[iam_policy_pb2.TestIamPermissionsResponse], + ]: + r"""Return a callable for the test iam permissions method over gRPC. + + Returns the permissions that a caller has on the + specified source. + + Returns: + Callable[[~.TestIamPermissionsRequest], + Awaitable[~.TestIamPermissionsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "test_iam_permissions" not in self._stubs: + self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/TestIamPermissions", + request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString, + response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString, + ) + return self._stubs["test_iam_permissions"] + + @property + def update_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.UpdateBigQueryExportRequest], + Awaitable[bigquery_export.BigQueryExport], + ]: + r"""Return a callable for the update big query export method over gRPC. + + Updates a BigQuery export. + + Returns: + Callable[[~.UpdateBigQueryExportRequest], + Awaitable[~.BigQueryExport]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_big_query_export" not in self._stubs: + self._stubs["update_big_query_export"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateBigQueryExport", + request_serializer=securitycenter_service.UpdateBigQueryExportRequest.serialize, + response_deserializer=bigquery_export.BigQueryExport.deserialize, + ) + return self._stubs["update_big_query_export"] + + @property + def update_external_system( + self, + ) -> Callable[ + [securitycenter_service.UpdateExternalSystemRequest], + Awaitable[gcs_external_system.ExternalSystem], + ]: + r"""Return a callable for the update external system method over gRPC. + + Updates external system. This is for a given finding. + If no location is specified, finding is assumed to be in + global + + Returns: + Callable[[~.UpdateExternalSystemRequest], + Awaitable[~.ExternalSystem]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_external_system" not in self._stubs: + self._stubs["update_external_system"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateExternalSystem", + request_serializer=securitycenter_service.UpdateExternalSystemRequest.serialize, + response_deserializer=gcs_external_system.ExternalSystem.deserialize, + ) + return self._stubs["update_external_system"] + + @property + def update_finding( + self, + ) -> Callable[ + [securitycenter_service.UpdateFindingRequest], Awaitable[gcs_finding.Finding] + ]: + r"""Return a callable for the update finding method over gRPC. + + Creates or updates a finding. If no location is + specified, finding is assumed to be in global. The + corresponding source must exist for a finding creation + to succeed. + + Returns: + Callable[[~.UpdateFindingRequest], + Awaitable[~.Finding]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_finding" not in self._stubs: + self._stubs["update_finding"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateFinding", + request_serializer=securitycenter_service.UpdateFindingRequest.serialize, + response_deserializer=gcs_finding.Finding.deserialize, + ) + return self._stubs["update_finding"] + + @property + def update_mute_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateMuteConfigRequest], + Awaitable[gcs_mute_config.MuteConfig], + ]: + r"""Return a callable for the update mute config method over gRPC. + + Updates a mute config. If no location is specified, + default is global. + + Returns: + Callable[[~.UpdateMuteConfigRequest], + Awaitable[~.MuteConfig]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_mute_config" not in self._stubs: + self._stubs["update_mute_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateMuteConfig", + request_serializer=securitycenter_service.UpdateMuteConfigRequest.serialize, + response_deserializer=gcs_mute_config.MuteConfig.deserialize, + ) + return self._stubs["update_mute_config"] + + @property + def update_notification_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateNotificationConfigRequest], + Awaitable[gcs_notification_config.NotificationConfig], + ]: + r"""Return a callable for the update notification config method over gRPC. + + Updates a notification config. The following update fields are + allowed: description, pubsub_topic, streaming_config.filter + + Returns: + Callable[[~.UpdateNotificationConfigRequest], + Awaitable[~.NotificationConfig]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_notification_config" not in self._stubs: + self._stubs["update_notification_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateNotificationConfig", + request_serializer=securitycenter_service.UpdateNotificationConfigRequest.serialize, + response_deserializer=gcs_notification_config.NotificationConfig.deserialize, + ) + return self._stubs["update_notification_config"] + + @property + def update_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateResourceValueConfigRequest], + Awaitable[gcs_resource_value_config.ResourceValueConfig], + ]: + r"""Return a callable for the update resource value config method over gRPC. + + Updates an existing ResourceValueConfigs with new + rules. + + Returns: + Callable[[~.UpdateResourceValueConfigRequest], + Awaitable[~.ResourceValueConfig]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_resource_value_config" not in self._stubs: + self._stubs["update_resource_value_config"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateResourceValueConfig", + request_serializer=securitycenter_service.UpdateResourceValueConfigRequest.serialize, + response_deserializer=gcs_resource_value_config.ResourceValueConfig.deserialize, + ) + return self._stubs["update_resource_value_config"] + + @property + def update_security_marks( + self, + ) -> Callable[ + [securitycenter_service.UpdateSecurityMarksRequest], + Awaitable[gcs_security_marks.SecurityMarks], + ]: + r"""Return a callable for the update security marks method over gRPC. + + Updates security marks. For Finding Security marks, + if no location is specified, finding is assumed to be in + global. Assets Security Marks can only be accessed + through global endpoint. + + Returns: + Callable[[~.UpdateSecurityMarksRequest], + Awaitable[~.SecurityMarks]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_security_marks" not in self._stubs: + self._stubs["update_security_marks"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateSecurityMarks", + request_serializer=securitycenter_service.UpdateSecurityMarksRequest.serialize, + response_deserializer=gcs_security_marks.SecurityMarks.deserialize, + ) + return self._stubs["update_security_marks"] + + @property + def update_source( + self, + ) -> Callable[ + [securitycenter_service.UpdateSourceRequest], Awaitable[gcs_source.Source] + ]: + r"""Return a callable for the update source method over gRPC. + + Updates a source. + + Returns: + Callable[[~.UpdateSourceRequest], + Awaitable[~.Source]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_source" not in self._stubs: + self._stubs["update_source"] = self.grpc_channel.unary_unary( + "/google.cloud.securitycenter.v2.SecurityCenter/UpdateSource", + request_serializer=securitycenter_service.UpdateSourceRequest.serialize, + response_deserializer=gcs_source.Source.deserialize, + ) + return self._stubs["update_source"] + + def close(self): + return self.grpc_channel.close() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ("SecurityCenterGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/rest.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/rest.py new file mode 100644 index 000000000000..92371b027a00 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/services/security_center/transports/rest.py @@ -0,0 +1,6583 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# + +import dataclasses +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import ( + gapic_v1, + operations_v1, + path_template, + rest_helpers, + rest_streaming, +) +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.protobuf import json_format +import grpc # type: ignore +from requests import __version__ as requests_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + + +from google.iam.v1 import iam_policy_pb2 # type: ignore +from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +from google.cloud.securitycenter_v2.types import securitycenter_service, simulation +from google.cloud.securitycenter_v2.types import external_system as gcs_external_system +from google.cloud.securitycenter_v2.types import ( + notification_config as gcs_notification_config, +) +from google.cloud.securitycenter_v2.types import ( + resource_value_config as gcs_resource_value_config, +) +from google.cloud.securitycenter_v2.types import security_marks as gcs_security_marks +from google.cloud.securitycenter_v2.types import bigquery_export +from google.cloud.securitycenter_v2.types import finding +from google.cloud.securitycenter_v2.types import finding as gcs_finding +from google.cloud.securitycenter_v2.types import mute_config +from google.cloud.securitycenter_v2.types import mute_config as gcs_mute_config +from google.cloud.securitycenter_v2.types import notification_config +from google.cloud.securitycenter_v2.types import resource_value_config +from google.cloud.securitycenter_v2.types import source +from google.cloud.securitycenter_v2.types import source as gcs_source +from google.cloud.securitycenter_v2.types import valued_resource + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .base import SecurityCenterTransport + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class SecurityCenterRestInterceptor: + """Interceptor for SecurityCenter. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the SecurityCenterRestTransport. + + .. code-block:: python + class MyCustomSecurityCenterInterceptor(SecurityCenterRestInterceptor): + def pre_batch_create_resource_value_configs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_create_resource_value_configs(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_bulk_mute_findings(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_bulk_mute_findings(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_big_query_export(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_big_query_export(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_finding(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_finding(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_mute_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_mute_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_notification_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_notification_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_source(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_source(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_big_query_export(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_mute_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_notification_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_resource_value_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_big_query_export(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_big_query_export(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_iam_policy(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_iam_policy(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_mute_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_mute_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_notification_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_notification_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_resource_value_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_resource_value_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_simulation(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_simulation(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_source(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_source(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_valued_resource(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_valued_resource(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_group_findings(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_group_findings(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_attack_paths(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_attack_paths(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_big_query_exports(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_big_query_exports(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_findings(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_findings(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_mute_configs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_mute_configs(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_notification_configs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_notification_configs(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_resource_value_configs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_resource_value_configs(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_sources(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_sources(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_valued_resources(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_valued_resources(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_set_finding_state(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_set_finding_state(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_set_iam_policy(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_set_iam_policy(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_set_mute(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_set_mute(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_test_iam_permissions(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_test_iam_permissions(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_big_query_export(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_big_query_export(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_external_system(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_external_system(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_finding(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_finding(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_mute_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_mute_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_notification_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_notification_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_resource_value_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_resource_value_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_security_marks(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_security_marks(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_source(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_source(self, response): + logging.log(f"Received response: {response}") + return response + + transport = SecurityCenterRestTransport(interceptor=MyCustomSecurityCenterInterceptor()) + client = SecurityCenterClient(transport=transport) + + + """ + + def pre_batch_create_resource_value_configs( + self, + request: securitycenter_service.BatchCreateResourceValueConfigsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.BatchCreateResourceValueConfigsRequest, + Sequence[Tuple[str, str]], + ]: + """Pre-rpc interceptor for batch_create_resource_value_configs + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_batch_create_resource_value_configs( + self, response: securitycenter_service.BatchCreateResourceValueConfigsResponse + ) -> securitycenter_service.BatchCreateResourceValueConfigsResponse: + """Post-rpc interceptor for batch_create_resource_value_configs + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_bulk_mute_findings( + self, + request: securitycenter_service.BulkMuteFindingsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.BulkMuteFindingsRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for bulk_mute_findings + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_bulk_mute_findings( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for bulk_mute_findings + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_create_big_query_export( + self, + request: securitycenter_service.CreateBigQueryExportRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.CreateBigQueryExportRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for create_big_query_export + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_create_big_query_export( + self, response: bigquery_export.BigQueryExport + ) -> bigquery_export.BigQueryExport: + """Post-rpc interceptor for create_big_query_export + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_create_finding( + self, + request: securitycenter_service.CreateFindingRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.CreateFindingRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_finding + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_create_finding(self, response: gcs_finding.Finding) -> gcs_finding.Finding: + """Post-rpc interceptor for create_finding + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_create_mute_config( + self, + request: securitycenter_service.CreateMuteConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.CreateMuteConfigRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for create_mute_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_create_mute_config( + self, response: gcs_mute_config.MuteConfig + ) -> gcs_mute_config.MuteConfig: + """Post-rpc interceptor for create_mute_config + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_create_notification_config( + self, + request: securitycenter_service.CreateNotificationConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.CreateNotificationConfigRequest, + Sequence[Tuple[str, str]], + ]: + """Pre-rpc interceptor for create_notification_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_create_notification_config( + self, response: gcs_notification_config.NotificationConfig + ) -> gcs_notification_config.NotificationConfig: + """Post-rpc interceptor for create_notification_config + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_create_source( + self, + request: securitycenter_service.CreateSourceRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.CreateSourceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_source + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_create_source(self, response: gcs_source.Source) -> gcs_source.Source: + """Post-rpc interceptor for create_source + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_delete_big_query_export( + self, + request: securitycenter_service.DeleteBigQueryExportRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.DeleteBigQueryExportRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for delete_big_query_export + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def pre_delete_mute_config( + self, + request: securitycenter_service.DeleteMuteConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.DeleteMuteConfigRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for delete_mute_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def pre_delete_notification_config( + self, + request: securitycenter_service.DeleteNotificationConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.DeleteNotificationConfigRequest, + Sequence[Tuple[str, str]], + ]: + """Pre-rpc interceptor for delete_notification_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def pre_delete_resource_value_config( + self, + request: securitycenter_service.DeleteResourceValueConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.DeleteResourceValueConfigRequest, + Sequence[Tuple[str, str]], + ]: + """Pre-rpc interceptor for delete_resource_value_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def pre_get_big_query_export( + self, + request: securitycenter_service.GetBigQueryExportRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.GetBigQueryExportRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for get_big_query_export + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_get_big_query_export( + self, response: bigquery_export.BigQueryExport + ) -> bigquery_export.BigQueryExport: + """Post-rpc interceptor for get_big_query_export + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_get_iam_policy( + self, + request: iam_policy_pb2.GetIamPolicyRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[iam_policy_pb2.GetIamPolicyRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_iam_policy + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_get_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy: + """Post-rpc interceptor for get_iam_policy + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_get_mute_config( + self, + request: securitycenter_service.GetMuteConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.GetMuteConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_mute_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_get_mute_config( + self, response: mute_config.MuteConfig + ) -> mute_config.MuteConfig: + """Post-rpc interceptor for get_mute_config + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_get_notification_config( + self, + request: securitycenter_service.GetNotificationConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.GetNotificationConfigRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for get_notification_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_get_notification_config( + self, response: notification_config.NotificationConfig + ) -> notification_config.NotificationConfig: + """Post-rpc interceptor for get_notification_config + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_get_resource_value_config( + self, + request: securitycenter_service.GetResourceValueConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.GetResourceValueConfigRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for get_resource_value_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_get_resource_value_config( + self, response: resource_value_config.ResourceValueConfig + ) -> resource_value_config.ResourceValueConfig: + """Post-rpc interceptor for get_resource_value_config + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_get_simulation( + self, + request: securitycenter_service.GetSimulationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.GetSimulationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_simulation + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_get_simulation( + self, response: simulation.Simulation + ) -> simulation.Simulation: + """Post-rpc interceptor for get_simulation + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_get_source( + self, + request: securitycenter_service.GetSourceRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.GetSourceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_source + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_get_source(self, response: source.Source) -> source.Source: + """Post-rpc interceptor for get_source + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_get_valued_resource( + self, + request: securitycenter_service.GetValuedResourceRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.GetValuedResourceRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for get_valued_resource + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_get_valued_resource( + self, response: valued_resource.ValuedResource + ) -> valued_resource.ValuedResource: + """Post-rpc interceptor for get_valued_resource + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_group_findings( + self, + request: securitycenter_service.GroupFindingsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.GroupFindingsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for group_findings + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_group_findings( + self, response: securitycenter_service.GroupFindingsResponse + ) -> securitycenter_service.GroupFindingsResponse: + """Post-rpc interceptor for group_findings + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_list_attack_paths( + self, + request: securitycenter_service.ListAttackPathsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.ListAttackPathsRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for list_attack_paths + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_list_attack_paths( + self, response: securitycenter_service.ListAttackPathsResponse + ) -> securitycenter_service.ListAttackPathsResponse: + """Post-rpc interceptor for list_attack_paths + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_list_big_query_exports( + self, + request: securitycenter_service.ListBigQueryExportsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.ListBigQueryExportsRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for list_big_query_exports + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_list_big_query_exports( + self, response: securitycenter_service.ListBigQueryExportsResponse + ) -> securitycenter_service.ListBigQueryExportsResponse: + """Post-rpc interceptor for list_big_query_exports + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_list_findings( + self, + request: securitycenter_service.ListFindingsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.ListFindingsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_findings + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_list_findings( + self, response: securitycenter_service.ListFindingsResponse + ) -> securitycenter_service.ListFindingsResponse: + """Post-rpc interceptor for list_findings + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_list_mute_configs( + self, + request: securitycenter_service.ListMuteConfigsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.ListMuteConfigsRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for list_mute_configs + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_list_mute_configs( + self, response: securitycenter_service.ListMuteConfigsResponse + ) -> securitycenter_service.ListMuteConfigsResponse: + """Post-rpc interceptor for list_mute_configs + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_list_notification_configs( + self, + request: securitycenter_service.ListNotificationConfigsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.ListNotificationConfigsRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for list_notification_configs + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_list_notification_configs( + self, response: securitycenter_service.ListNotificationConfigsResponse + ) -> securitycenter_service.ListNotificationConfigsResponse: + """Post-rpc interceptor for list_notification_configs + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_list_resource_value_configs( + self, + request: securitycenter_service.ListResourceValueConfigsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.ListResourceValueConfigsRequest, + Sequence[Tuple[str, str]], + ]: + """Pre-rpc interceptor for list_resource_value_configs + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_list_resource_value_configs( + self, response: securitycenter_service.ListResourceValueConfigsResponse + ) -> securitycenter_service.ListResourceValueConfigsResponse: + """Post-rpc interceptor for list_resource_value_configs + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_list_sources( + self, + request: securitycenter_service.ListSourcesRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.ListSourcesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_sources + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_list_sources( + self, response: securitycenter_service.ListSourcesResponse + ) -> securitycenter_service.ListSourcesResponse: + """Post-rpc interceptor for list_sources + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_list_valued_resources( + self, + request: securitycenter_service.ListValuedResourcesRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.ListValuedResourcesRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for list_valued_resources + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_list_valued_resources( + self, response: securitycenter_service.ListValuedResourcesResponse + ) -> securitycenter_service.ListValuedResourcesResponse: + """Post-rpc interceptor for list_valued_resources + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_set_finding_state( + self, + request: securitycenter_service.SetFindingStateRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.SetFindingStateRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for set_finding_state + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_set_finding_state(self, response: finding.Finding) -> finding.Finding: + """Post-rpc interceptor for set_finding_state + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_set_iam_policy( + self, + request: iam_policy_pb2.SetIamPolicyRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[iam_policy_pb2.SetIamPolicyRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for set_iam_policy + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_set_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy: + """Post-rpc interceptor for set_iam_policy + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_set_mute( + self, + request: securitycenter_service.SetMuteRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.SetMuteRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for set_mute + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_set_mute(self, response: finding.Finding) -> finding.Finding: + """Post-rpc interceptor for set_mute + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_test_iam_permissions( + self, + request: iam_policy_pb2.TestIamPermissionsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[iam_policy_pb2.TestIamPermissionsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for test_iam_permissions + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_test_iam_permissions( + self, response: iam_policy_pb2.TestIamPermissionsResponse + ) -> iam_policy_pb2.TestIamPermissionsResponse: + """Post-rpc interceptor for test_iam_permissions + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_update_big_query_export( + self, + request: securitycenter_service.UpdateBigQueryExportRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.UpdateBigQueryExportRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for update_big_query_export + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_update_big_query_export( + self, response: bigquery_export.BigQueryExport + ) -> bigquery_export.BigQueryExport: + """Post-rpc interceptor for update_big_query_export + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_update_external_system( + self, + request: securitycenter_service.UpdateExternalSystemRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.UpdateExternalSystemRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for update_external_system + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_update_external_system( + self, response: gcs_external_system.ExternalSystem + ) -> gcs_external_system.ExternalSystem: + """Post-rpc interceptor for update_external_system + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_update_finding( + self, + request: securitycenter_service.UpdateFindingRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.UpdateFindingRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_finding + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_update_finding(self, response: gcs_finding.Finding) -> gcs_finding.Finding: + """Post-rpc interceptor for update_finding + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_update_mute_config( + self, + request: securitycenter_service.UpdateMuteConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.UpdateMuteConfigRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for update_mute_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_update_mute_config( + self, response: gcs_mute_config.MuteConfig + ) -> gcs_mute_config.MuteConfig: + """Post-rpc interceptor for update_mute_config + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_update_notification_config( + self, + request: securitycenter_service.UpdateNotificationConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.UpdateNotificationConfigRequest, + Sequence[Tuple[str, str]], + ]: + """Pre-rpc interceptor for update_notification_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_update_notification_config( + self, response: gcs_notification_config.NotificationConfig + ) -> gcs_notification_config.NotificationConfig: + """Post-rpc interceptor for update_notification_config + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_update_resource_value_config( + self, + request: securitycenter_service.UpdateResourceValueConfigRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.UpdateResourceValueConfigRequest, + Sequence[Tuple[str, str]], + ]: + """Pre-rpc interceptor for update_resource_value_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_update_resource_value_config( + self, response: gcs_resource_value_config.ResourceValueConfig + ) -> gcs_resource_value_config.ResourceValueConfig: + """Post-rpc interceptor for update_resource_value_config + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_update_security_marks( + self, + request: securitycenter_service.UpdateSecurityMarksRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[ + securitycenter_service.UpdateSecurityMarksRequest, Sequence[Tuple[str, str]] + ]: + """Pre-rpc interceptor for update_security_marks + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_update_security_marks( + self, response: gcs_security_marks.SecurityMarks + ) -> gcs_security_marks.SecurityMarks: + """Post-rpc interceptor for update_security_marks + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_update_source( + self, + request: securitycenter_service.UpdateSourceRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[securitycenter_service.UpdateSourceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_source + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_update_source(self, response: gcs_source.Source) -> gcs_source.Source: + """Post-rpc interceptor for update_source + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_cancel_operation( + self, + request: operations_pb2.CancelOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.CancelOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_cancel_operation(self, response: None) -> None: + """Post-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_delete_operation( + self, + request: operations_pb2.DeleteOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.DeleteOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_delete_operation(self, response: None) -> None: + """Post-rpc interceptor for delete_operation + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the SecurityCenter server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the SecurityCenter server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class SecurityCenterRestStub: + _session: AuthorizedSession + _host: str + _interceptor: SecurityCenterRestInterceptor + + +class SecurityCenterRestTransport(SecurityCenterTransport): + """REST backend transport for SecurityCenter. + + V2 APIs for Security Center service. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__( + self, + *, + host: str = "securitycenter.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[SecurityCenterRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'securitycenter.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` 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 are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or SecurityCenterRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.CancelOperation": [ + { + "method": "post", + "uri": "/v2/{name=organizations/*/operations/*}:cancel", + }, + ], + "google.longrunning.Operations.DeleteOperation": [ + { + "method": "delete", + "uri": "/v2/{name=organizations/*/operations/*}", + }, + ], + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/operations/*}", + }, + ], + "google.longrunning.Operations.ListOperations": [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/operations}", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v2", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _BatchCreateResourceValueConfigs(SecurityCenterRestStub): + def __hash__(self): + return hash("BatchCreateResourceValueConfigs") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.BatchCreateResourceValueConfigsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.BatchCreateResourceValueConfigsResponse: + r"""Call the batch create resource + value configs method over HTTP. + + Args: + request (~.securitycenter_service.BatchCreateResourceValueConfigsRequest): + The request object. Request message to create multiple + resource value configs + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.securitycenter_service.BatchCreateResourceValueConfigsResponse: + Response message for + BatchCreateResourceValueConfigs + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{parent=organizations/*}/resourceValueConfigs:batchCreate", + "body": "*", + }, + ] + ( + request, + metadata, + ) = self._interceptor.pre_batch_create_resource_value_configs( + request, metadata + ) + pb_request = ( + securitycenter_service.BatchCreateResourceValueConfigsRequest.pb( + request + ) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = securitycenter_service.BatchCreateResourceValueConfigsResponse() + pb_resp = securitycenter_service.BatchCreateResourceValueConfigsResponse.pb( + resp + ) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_create_resource_value_configs(resp) + return resp + + class _BulkMuteFindings(SecurityCenterRestStub): + def __hash__(self): + return hash("BulkMuteFindings") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.BulkMuteFindingsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the bulk mute findings method over HTTP. + + Args: + request (~.securitycenter_service.BulkMuteFindingsRequest): + The request object. Request message for bulk findings + update. + Note: + + 1. If multiple bulk update requests + match the same resource, the order + in which they get executed is not + defined. + 2. Once a bulk operation is started, + there is no way to stop it. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{parent=organizations/*}/findings:bulkMute", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{parent=organizations/*/locations/*}/findings:bulkMute", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{parent=folders/*}/findings:bulkMute", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{parent=folders/*/locations/*}/findings:bulkMute", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{parent=projects/*}/findings:bulkMute", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{parent=projects/*/locations/*}/findings:bulkMute", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_bulk_mute_findings( + request, metadata + ) + pb_request = securitycenter_service.BulkMuteFindingsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_bulk_mute_findings(resp) + return resp + + class _CreateBigQueryExport(SecurityCenterRestStub): + def __hash__(self): + return hash("CreateBigQueryExport") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "bigQueryExportId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.CreateBigQueryExportRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bigquery_export.BigQueryExport: + r"""Call the create big query export method over HTTP. + + Args: + request (~.securitycenter_service.CreateBigQueryExportRequest): + The request object. Request message for creating a + BigQuery export. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.bigquery_export.BigQueryExport: + Configures how to deliver Findings to + BigQuery Instance. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{parent=organizations/*/locations/*}/bigQueryExports", + "body": "big_query_export", + }, + { + "method": "post", + "uri": "/v2/{parent=folders/*/locations/*}/bigQueryExports", + "body": "big_query_export", + }, + { + "method": "post", + "uri": "/v2/{parent=projects/*/locations/*}/bigQueryExports", + "body": "big_query_export", + }, + ] + request, metadata = self._interceptor.pre_create_big_query_export( + request, metadata + ) + pb_request = securitycenter_service.CreateBigQueryExportRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = bigquery_export.BigQueryExport() + pb_resp = bigquery_export.BigQueryExport.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_big_query_export(resp) + return resp + + class _CreateFinding(SecurityCenterRestStub): + def __hash__(self): + return hash("CreateFinding") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "findingId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.CreateFindingRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_finding.Finding: + r"""Call the create finding method over HTTP. + + Args: + request (~.securitycenter_service.CreateFindingRequest): + The request object. Request message for creating a + finding. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_finding.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{parent=organizations/*/sources/*/locations/*}/findings", + "body": "finding", + }, + { + "method": "post", + "uri": "/v2/{parent=organizations/*/sources/*}/findings", + "body": "finding", + }, + ] + request, metadata = self._interceptor.pre_create_finding(request, metadata) + pb_request = securitycenter_service.CreateFindingRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_finding.Finding() + pb_resp = gcs_finding.Finding.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_finding(resp) + return resp + + class _CreateMuteConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("CreateMuteConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "muteConfigId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.CreateMuteConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_mute_config.MuteConfig: + r"""Call the create mute config method over HTTP. + + Args: + request (~.securitycenter_service.CreateMuteConfigRequest): + The request object. Request message for creating a mute + config. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_mute_config.MuteConfig: + A mute config is a Cloud SCC resource + that contains the configuration to mute + create/update events of findings. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{parent=organizations/*/locations/*}/muteConfigs", + "body": "mute_config", + }, + { + "method": "post", + "uri": "/v2/{parent=folders/*/locations/*}/muteConfigs", + "body": "mute_config", + }, + { + "method": "post", + "uri": "/v2/{parent=projects/*/locations/*}/muteConfigs", + "body": "mute_config", + }, + { + "method": "post", + "uri": "/v2/{parent=organizations/*}/muteConfigs", + "body": "mute_config", + }, + { + "method": "post", + "uri": "/v2/{parent=folders/*}/muteConfigs", + "body": "mute_config", + }, + { + "method": "post", + "uri": "/v2/{parent=projects/*}/muteConfigs", + "body": "mute_config", + }, + ] + request, metadata = self._interceptor.pre_create_mute_config( + request, metadata + ) + pb_request = securitycenter_service.CreateMuteConfigRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_mute_config.MuteConfig() + pb_resp = gcs_mute_config.MuteConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_mute_config(resp) + return resp + + class _CreateNotificationConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("CreateNotificationConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "configId": "", + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.CreateNotificationConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_notification_config.NotificationConfig: + r"""Call the create notification + config method over HTTP. + + Args: + request (~.securitycenter_service.CreateNotificationConfigRequest): + The request object. Request message for creating a + notification config. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_notification_config.NotificationConfig: + Cloud Security Command Center (Cloud + SCC) notification configs. + A notification config is a Cloud SCC + resource that contains the configuration + to send notifications for create/update + events of findings, assets and etc. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{parent=organizations/*/locations/*}/notificationConfigs", + "body": "notification_config", + }, + { + "method": "post", + "uri": "/v2/{parent=folders/*/locations/*}/notificationConfigs", + "body": "notification_config", + }, + { + "method": "post", + "uri": "/v2/{parent=projects/*/locations/*}/notificationConfigs", + "body": "notification_config", + }, + ] + request, metadata = self._interceptor.pre_create_notification_config( + request, metadata + ) + pb_request = securitycenter_service.CreateNotificationConfigRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_notification_config.NotificationConfig() + pb_resp = gcs_notification_config.NotificationConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_notification_config(resp) + return resp + + class _CreateSource(SecurityCenterRestStub): + def __hash__(self): + return hash("CreateSource") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.CreateSourceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_source.Source: + r"""Call the create source method over HTTP. + + Args: + request (~.securitycenter_service.CreateSourceRequest): + The request object. Request message for creating a + source. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_source.Source: + Security Command Center finding + source. A finding source is an entity or + a mechanism that can produce a finding. + A source is like a container of findings + that come from the same scanner, logger, + monitor, and other tools. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{parent=organizations/*}/sources", + "body": "source", + }, + ] + request, metadata = self._interceptor.pre_create_source(request, metadata) + pb_request = securitycenter_service.CreateSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_source.Source() + pb_resp = gcs_source.Source.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_source(resp) + return resp + + class _DeleteBigQueryExport(SecurityCenterRestStub): + def __hash__(self): + return hash("DeleteBigQueryExport") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.DeleteBigQueryExportRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ): + r"""Call the delete big query export method over HTTP. + + Args: + request (~.securitycenter_service.DeleteBigQueryExportRequest): + The request object. Request message for deleting a + BigQuery export. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2/{name=organizations/*/locations/*/bigQueryExports/*}", + }, + { + "method": "delete", + "uri": "/v2/{name=folders/*/locations/*/bigQueryExports/*}", + }, + { + "method": "delete", + "uri": "/v2/{name=projects/*/locations/*/bigQueryExports/*}", + }, + ] + request, metadata = self._interceptor.pre_delete_big_query_export( + request, metadata + ) + pb_request = securitycenter_service.DeleteBigQueryExportRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteMuteConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("DeleteMuteConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.DeleteMuteConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ): + r"""Call the delete mute config method over HTTP. + + Args: + request (~.securitycenter_service.DeleteMuteConfigRequest): + The request object. Request message for deleting a mute + config. If no location is specified, + default is global. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2/{name=organizations/*/muteConfigs/*}", + }, + { + "method": "delete", + "uri": "/v2/{name=organizations/*/locations/*/muteConfigs/*}", + }, + { + "method": "delete", + "uri": "/v2/{name=folders/*/muteConfigs/*}", + }, + { + "method": "delete", + "uri": "/v2/{name=folders/*/locations/*/muteConfigs/*}", + }, + { + "method": "delete", + "uri": "/v2/{name=projects/*/muteConfigs/*}", + }, + { + "method": "delete", + "uri": "/v2/{name=projects/*/locations/*/muteConfigs/*}", + }, + ] + request, metadata = self._interceptor.pre_delete_mute_config( + request, metadata + ) + pb_request = securitycenter_service.DeleteMuteConfigRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteNotificationConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("DeleteNotificationConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.DeleteNotificationConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ): + r"""Call the delete notification + config method over HTTP. + + Args: + request (~.securitycenter_service.DeleteNotificationConfigRequest): + The request object. Request message for deleting a + notification config. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2/{name=organizations/*/locations/*/notificationConfigs/*}", + }, + { + "method": "delete", + "uri": "/v2/{name=folders/*/locations/*/notificationConfigs/*}", + }, + { + "method": "delete", + "uri": "/v2/{name=projects/*/locations/*/notificationConfigs/*}", + }, + ] + request, metadata = self._interceptor.pre_delete_notification_config( + request, metadata + ) + pb_request = securitycenter_service.DeleteNotificationConfigRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteResourceValueConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("DeleteResourceValueConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.DeleteResourceValueConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ): + r"""Call the delete resource value + config method over HTTP. + + Args: + request (~.securitycenter_service.DeleteResourceValueConfigRequest): + The request object. Request message to delete resource + value config + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2/{name=organizations/*/resourceValueConfigs/*}", + }, + ] + request, metadata = self._interceptor.pre_delete_resource_value_config( + request, metadata + ) + pb_request = securitycenter_service.DeleteResourceValueConfigRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _GetBigQueryExport(SecurityCenterRestStub): + def __hash__(self): + return hash("GetBigQueryExport") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.GetBigQueryExportRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bigquery_export.BigQueryExport: + r"""Call the get big query export method over HTTP. + + Args: + request (~.securitycenter_service.GetBigQueryExportRequest): + The request object. Request message for retrieving a + BigQuery export. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.bigquery_export.BigQueryExport: + Configures how to deliver Findings to + BigQuery Instance. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/locations/*/bigQueryExports/*}", + }, + { + "method": "get", + "uri": "/v2/{name=folders/*/locations/*/bigQueryExports/*}", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/bigQueryExports/*}", + }, + ] + request, metadata = self._interceptor.pre_get_big_query_export( + request, metadata + ) + pb_request = securitycenter_service.GetBigQueryExportRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = bigquery_export.BigQueryExport() + pb_resp = bigquery_export.BigQueryExport.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_big_query_export(resp) + return resp + + class _GetIamPolicy(SecurityCenterRestStub): + def __hash__(self): + return hash("GetIamPolicy") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: iam_policy_pb2.GetIamPolicyRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> policy_pb2.Policy: + r"""Call the get iam policy method over HTTP. + + Args: + request (~.iam_policy_pb2.GetIamPolicyRequest): + The request object. Request message for ``GetIamPolicy`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.policy_pb2.Policy: + An Identity and Access Management (IAM) policy, which + specifies access controls for Google Cloud resources. + + A ``Policy`` is a collection of ``bindings``. A + ``binding`` binds one or more ``members``, or + principals, to a single ``role``. Principals can be user + accounts, service accounts, Google groups, and domains + (such as G Suite). A ``role`` is a named list of + permissions; each ``role`` can be an IAM predefined role + or a user-created custom role. + + For some types of Google Cloud resources, a ``binding`` + can also specify a ``condition``, which is a logical + expression that allows access to a resource only if the + expression evaluates to ``true``. A condition can add + constraints based on attributes of the request, the + resource, or both. To learn which resources support + conditions in their IAM policies, see the `IAM + documentation `__. + + **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')", + } + } + ], + "etag": "BwWWja0YfJA=", + "version": 3 + } + + **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') + etag: BwWWja0YfJA= + version: 3 + + For a description of IAM and its features, see the `IAM + documentation `__. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{resource=organizations/*/sources/*}:getIamPolicy", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_get_iam_policy(request, metadata) + pb_request = request + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = policy_pb2.Policy() + pb_resp = resp + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_iam_policy(resp) + return resp + + class _GetMuteConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("GetMuteConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.GetMuteConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> mute_config.MuteConfig: + r"""Call the get mute config method over HTTP. + + Args: + request (~.securitycenter_service.GetMuteConfigRequest): + The request object. Request message for retrieving a mute + config. If no location is specified, + default is global. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.mute_config.MuteConfig: + A mute config is a Cloud SCC resource + that contains the configuration to mute + create/update events of findings. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/muteConfigs/*}", + }, + { + "method": "get", + "uri": "/v2/{name=organizations/*/locations/*/muteConfigs/*}", + }, + { + "method": "get", + "uri": "/v2/{name=folders/*/muteConfigs/*}", + }, + { + "method": "get", + "uri": "/v2/{name=folders/*/locations/*/muteConfigs/*}", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/muteConfigs/*}", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/muteConfigs/*}", + }, + ] + request, metadata = self._interceptor.pre_get_mute_config(request, metadata) + pb_request = securitycenter_service.GetMuteConfigRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = mute_config.MuteConfig() + pb_resp = mute_config.MuteConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_mute_config(resp) + return resp + + class _GetNotificationConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("GetNotificationConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.GetNotificationConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> notification_config.NotificationConfig: + r"""Call the get notification config method over HTTP. + + Args: + request (~.securitycenter_service.GetNotificationConfigRequest): + The request object. Request message for getting a + notification config. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.notification_config.NotificationConfig: + Cloud Security Command Center (Cloud + SCC) notification configs. + A notification config is a Cloud SCC + resource that contains the configuration + to send notifications for create/update + events of findings, assets and etc. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/locations/*/notificationConfigs/*}", + }, + { + "method": "get", + "uri": "/v2/{name=folders/*/locations/*/notificationConfigs/*}", + }, + { + "method": "get", + "uri": "/v2/{name=projects/*/locations/*/notificationConfigs/*}", + }, + ] + request, metadata = self._interceptor.pre_get_notification_config( + request, metadata + ) + pb_request = securitycenter_service.GetNotificationConfigRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = notification_config.NotificationConfig() + pb_resp = notification_config.NotificationConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_notification_config(resp) + return resp + + class _GetResourceValueConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("GetResourceValueConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.GetResourceValueConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resource_value_config.ResourceValueConfig: + r"""Call the get resource value config method over HTTP. + + Args: + request (~.securitycenter_service.GetResourceValueConfigRequest): + The request object. Request message to get resource value + config + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.resource_value_config.ResourceValueConfig: + A resource value config (RVC) is a + mapping configuration of user's + resources to resource values. Used in + Attack path simulations. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/resourceValueConfigs/*}", + }, + ] + request, metadata = self._interceptor.pre_get_resource_value_config( + request, metadata + ) + pb_request = securitycenter_service.GetResourceValueConfigRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = resource_value_config.ResourceValueConfig() + pb_resp = resource_value_config.ResourceValueConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_resource_value_config(resp) + return resp + + class _GetSimulation(SecurityCenterRestStub): + def __hash__(self): + return hash("GetSimulation") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.GetSimulationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> simulation.Simulation: + r"""Call the get simulation method over HTTP. + + Args: + request (~.securitycenter_service.GetSimulationRequest): + The request object. Request message for getting + simulation. Simulation name can include + "latest" to retrieve the latest + simulation For example, + "organizations/123/simulations/latest". + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.simulation.Simulation: + Attack path simulation + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/simulations/*}", + }, + ] + request, metadata = self._interceptor.pre_get_simulation(request, metadata) + pb_request = securitycenter_service.GetSimulationRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = simulation.Simulation() + pb_resp = simulation.Simulation.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_simulation(resp) + return resp + + class _GetSource(SecurityCenterRestStub): + def __hash__(self): + return hash("GetSource") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.GetSourceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> source.Source: + r"""Call the get source method over HTTP. + + Args: + request (~.securitycenter_service.GetSourceRequest): + The request object. Request message for getting a source. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.source.Source: + Security Command Center finding + source. A finding source is an entity or + a mechanism that can produce a finding. + A source is like a container of findings + that come from the same scanner, logger, + monitor, and other tools. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/sources/*}", + }, + ] + request, metadata = self._interceptor.pre_get_source(request, metadata) + pb_request = securitycenter_service.GetSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = source.Source() + pb_resp = source.Source.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_source(resp) + return resp + + class _GetValuedResource(SecurityCenterRestStub): + def __hash__(self): + return hash("GetValuedResource") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.GetValuedResourceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> valued_resource.ValuedResource: + r"""Call the get valued resource method over HTTP. + + Args: + request (~.securitycenter_service.GetValuedResourceRequest): + The request object. Request message for getting a valued + resource. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.valued_resource.ValuedResource: + A resource that is determined to have + value to a user's system + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/simulations/*/valuedResources/*}", + }, + ] + request, metadata = self._interceptor.pre_get_valued_resource( + request, metadata + ) + pb_request = securitycenter_service.GetValuedResourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = valued_resource.ValuedResource() + pb_resp = valued_resource.ValuedResource.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_valued_resource(resp) + return resp + + class _GroupFindings(SecurityCenterRestStub): + def __hash__(self): + return hash("GroupFindings") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.GroupFindingsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.GroupFindingsResponse: + r"""Call the group findings method over HTTP. + + Args: + request (~.securitycenter_service.GroupFindingsRequest): + The request object. Request message for grouping by + findings. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.securitycenter_service.GroupFindingsResponse: + Response message for group by + findings. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{parent=organizations/*/sources/*}/findings:group", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{parent=organizations/*/sources/*/locations/*}/findings:group", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{parent=folders/*/sources/*}/findings:group", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{parent=folders/*/sources/*/locations/*}/findings:group", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{parent=projects/*/sources/*}/findings:group", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{parent=projects/*/sources/*/locations/*}/findings:group", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_group_findings(request, metadata) + pb_request = securitycenter_service.GroupFindingsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = securitycenter_service.GroupFindingsResponse() + pb_resp = securitycenter_service.GroupFindingsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_group_findings(resp) + return resp + + class _ListAttackPaths(SecurityCenterRestStub): + def __hash__(self): + return hash("ListAttackPaths") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.ListAttackPathsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.ListAttackPathsResponse: + r"""Call the list attack paths method over HTTP. + + Args: + request (~.securitycenter_service.ListAttackPathsRequest): + The request object. Request message for listing the + attack paths for a given simulation or + valued resource. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.securitycenter_service.ListAttackPathsResponse: + Response message for listing the + attack paths for a given simulation or + valued resource. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{parent=organizations/*/simulations/*}/attackPaths", + }, + { + "method": "get", + "uri": "/v2/{parent=organizations/*/simulations/*/valuedResources/*}/attackPaths", + }, + { + "method": "get", + "uri": "/v2/{parent=organizations/*/simulations/*/attackExposureResults/*}/attackPaths", + }, + ] + request, metadata = self._interceptor.pre_list_attack_paths( + request, metadata + ) + pb_request = securitycenter_service.ListAttackPathsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = securitycenter_service.ListAttackPathsResponse() + pb_resp = securitycenter_service.ListAttackPathsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_attack_paths(resp) + return resp + + class _ListBigQueryExports(SecurityCenterRestStub): + def __hash__(self): + return hash("ListBigQueryExports") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.ListBigQueryExportsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.ListBigQueryExportsResponse: + r"""Call the list big query exports method over HTTP. + + Args: + request (~.securitycenter_service.ListBigQueryExportsRequest): + The request object. Request message for listing BigQuery + exports at a given scope e.g. + organization, folder or project. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.securitycenter_service.ListBigQueryExportsResponse: + Response message for listing BigQuery + exports. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{parent=organizations/*/locations/*}/bigQueryExports", + }, + { + "method": "get", + "uri": "/v2/{parent=folders/*/locations/*}/bigQueryExports", + }, + { + "method": "get", + "uri": "/v2/{parent=projects/*/locations/*}/bigQueryExports", + }, + ] + request, metadata = self._interceptor.pre_list_big_query_exports( + request, metadata + ) + pb_request = securitycenter_service.ListBigQueryExportsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = securitycenter_service.ListBigQueryExportsResponse() + pb_resp = securitycenter_service.ListBigQueryExportsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_big_query_exports(resp) + return resp + + class _ListFindings(SecurityCenterRestStub): + def __hash__(self): + return hash("ListFindings") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.ListFindingsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.ListFindingsResponse: + r"""Call the list findings method over HTTP. + + Args: + request (~.securitycenter_service.ListFindingsRequest): + The request object. Request message for listing findings. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.securitycenter_service.ListFindingsResponse: + Response message for listing + findings. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{parent=organizations/*/sources/*}/findings", + }, + { + "method": "get", + "uri": "/v2/{parent=organizations/*/sources/*/locations/*}/findings", + }, + { + "method": "get", + "uri": "/v2/{parent=folders/*/sources/*}/findings", + }, + { + "method": "get", + "uri": "/v2/{parent=folders/*/sources/*/locations/*}/findings", + }, + { + "method": "get", + "uri": "/v2/{parent=projects/*/sources/*}/findings", + }, + { + "method": "get", + "uri": "/v2/{parent=projects/*/sources/*/locations/*}/findings", + }, + ] + request, metadata = self._interceptor.pre_list_findings(request, metadata) + pb_request = securitycenter_service.ListFindingsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = securitycenter_service.ListFindingsResponse() + pb_resp = securitycenter_service.ListFindingsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_findings(resp) + return resp + + class _ListMuteConfigs(SecurityCenterRestStub): + def __hash__(self): + return hash("ListMuteConfigs") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.ListMuteConfigsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.ListMuteConfigsResponse: + r"""Call the list mute configs method over HTTP. + + Args: + request (~.securitycenter_service.ListMuteConfigsRequest): + The request object. Request message for listing mute + configs at a given scope e.g. + organization, folder or project. If no + location is specified, default is + global. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.securitycenter_service.ListMuteConfigsResponse: + Response message for listing mute + configs. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{parent=organizations/*}/muteConfigs", + }, + { + "method": "get", + "uri": "/v2/{parent=organizations/*/locations/*}/muteConfigs", + }, + { + "method": "get", + "uri": "/v2/{parent=folders/*}/muteConfigs", + }, + { + "method": "get", + "uri": "/v2/{parent=folders/*/locations/*}/muteConfigs", + }, + { + "method": "get", + "uri": "/v2/{parent=projects/*}/muteConfigs", + }, + { + "method": "get", + "uri": "/v2/{parent=projects/*/locations/*}/muteConfigs", + }, + ] + request, metadata = self._interceptor.pre_list_mute_configs( + request, metadata + ) + pb_request = securitycenter_service.ListMuteConfigsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = securitycenter_service.ListMuteConfigsResponse() + pb_resp = securitycenter_service.ListMuteConfigsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_mute_configs(resp) + return resp + + class _ListNotificationConfigs(SecurityCenterRestStub): + def __hash__(self): + return hash("ListNotificationConfigs") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.ListNotificationConfigsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.ListNotificationConfigsResponse: + r"""Call the list notification configs method over HTTP. + + Args: + request (~.securitycenter_service.ListNotificationConfigsRequest): + The request object. Request message for listing + notification configs. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.securitycenter_service.ListNotificationConfigsResponse: + Response message for listing + notification configs. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{parent=organizations/*/locations/*}/notificationConfigs", + }, + { + "method": "get", + "uri": "/v2/{parent=folders/*/locations/*}/notificationConfigs", + }, + { + "method": "get", + "uri": "/v2/{parent=projects/*/locations/*}/notificationConfigs", + }, + ] + request, metadata = self._interceptor.pre_list_notification_configs( + request, metadata + ) + pb_request = securitycenter_service.ListNotificationConfigsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = securitycenter_service.ListNotificationConfigsResponse() + pb_resp = securitycenter_service.ListNotificationConfigsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_notification_configs(resp) + return resp + + class _ListResourceValueConfigs(SecurityCenterRestStub): + def __hash__(self): + return hash("ListResourceValueConfigs") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.ListResourceValueConfigsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.ListResourceValueConfigsResponse: + r"""Call the list resource value + configs method over HTTP. + + Args: + request (~.securitycenter_service.ListResourceValueConfigsRequest): + The request object. Request message to list resource + value configs of a parent + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.securitycenter_service.ListResourceValueConfigsResponse: + Response message to list resource + value configs + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{parent=organizations/*}/resourceValueConfigs", + }, + ] + request, metadata = self._interceptor.pre_list_resource_value_configs( + request, metadata + ) + pb_request = securitycenter_service.ListResourceValueConfigsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = securitycenter_service.ListResourceValueConfigsResponse() + pb_resp = securitycenter_service.ListResourceValueConfigsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_resource_value_configs(resp) + return resp + + class _ListSources(SecurityCenterRestStub): + def __hash__(self): + return hash("ListSources") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.ListSourcesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.ListSourcesResponse: + r"""Call the list sources method over HTTP. + + Args: + request (~.securitycenter_service.ListSourcesRequest): + The request object. Request message for listing sources. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.securitycenter_service.ListSourcesResponse: + Response message for listing sources. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{parent=organizations/*}/sources", + }, + { + "method": "get", + "uri": "/v2/{parent=folders/*}/sources", + }, + { + "method": "get", + "uri": "/v2/{parent=projects/*}/sources", + }, + ] + request, metadata = self._interceptor.pre_list_sources(request, metadata) + pb_request = securitycenter_service.ListSourcesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = securitycenter_service.ListSourcesResponse() + pb_resp = securitycenter_service.ListSourcesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_sources(resp) + return resp + + class _ListValuedResources(SecurityCenterRestStub): + def __hash__(self): + return hash("ListValuedResources") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.ListValuedResourcesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> securitycenter_service.ListValuedResourcesResponse: + r"""Call the list valued resources method over HTTP. + + Args: + request (~.securitycenter_service.ListValuedResourcesRequest): + The request object. Request message for listing the + valued resources for a given simulation. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.securitycenter_service.ListValuedResourcesResponse: + Response message for listing the + valued resources for a given simulation. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{parent=organizations/*/simulations/*}/valuedResources", + }, + { + "method": "get", + "uri": "/v2/{parent=organizations/*/simulations/*/attackExposureResults/*}/valuedResources", + }, + ] + request, metadata = self._interceptor.pre_list_valued_resources( + request, metadata + ) + pb_request = securitycenter_service.ListValuedResourcesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = securitycenter_service.ListValuedResourcesResponse() + pb_resp = securitycenter_service.ListValuedResourcesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_valued_resources(resp) + return resp + + class _SetFindingState(SecurityCenterRestStub): + def __hash__(self): + return hash("SetFindingState") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.SetFindingStateRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> finding.Finding: + r"""Call the set finding state method over HTTP. + + Args: + request (~.securitycenter_service.SetFindingStateRequest): + The request object. Request message for updating a + finding's state. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.finding.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{name=organizations/*/sources/*/findings/*}:setState", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{name=organizations/*/sources/*/locations/*/findings/*}:setState", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{name=folders/*/sources/*/findings/*}:setState", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{name=folders/*/sources/*/locations/*/findings/*}:setState", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{name=projects/*/sources/*/findings/*}:setState", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{name=projects/*/sources/*/locations/*/findings/*}:setState", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_set_finding_state( + request, metadata + ) + pb_request = securitycenter_service.SetFindingStateRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = finding.Finding() + pb_resp = finding.Finding.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_set_finding_state(resp) + return resp + + class _SetIamPolicy(SecurityCenterRestStub): + def __hash__(self): + return hash("SetIamPolicy") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: iam_policy_pb2.SetIamPolicyRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> policy_pb2.Policy: + r"""Call the set iam policy method over HTTP. + + Args: + request (~.iam_policy_pb2.SetIamPolicyRequest): + The request object. Request message for ``SetIamPolicy`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.policy_pb2.Policy: + An Identity and Access Management (IAM) policy, which + specifies access controls for Google Cloud resources. + + A ``Policy`` is a collection of ``bindings``. A + ``binding`` binds one or more ``members``, or + principals, to a single ``role``. Principals can be user + accounts, service accounts, Google groups, and domains + (such as G Suite). A ``role`` is a named list of + permissions; each ``role`` can be an IAM predefined role + or a user-created custom role. + + For some types of Google Cloud resources, a ``binding`` + can also specify a ``condition``, which is a logical + expression that allows access to a resource only if the + expression evaluates to ``true``. A condition can add + constraints based on attributes of the request, the + resource, or both. To learn which resources support + conditions in their IAM policies, see the `IAM + documentation `__. + + **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')", + } + } + ], + "etag": "BwWWja0YfJA=", + "version": 3 + } + + **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') + etag: BwWWja0YfJA= + version: 3 + + For a description of IAM and its features, see the `IAM + documentation `__. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{resource=organizations/*/sources/*}:setIamPolicy", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_set_iam_policy(request, metadata) + pb_request = request + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = policy_pb2.Policy() + pb_resp = resp + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_set_iam_policy(resp) + return resp + + class _SetMute(SecurityCenterRestStub): + def __hash__(self): + return hash("SetMute") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.SetMuteRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> finding.Finding: + r"""Call the set mute method over HTTP. + + Args: + request (~.securitycenter_service.SetMuteRequest): + The request object. Request message for updating a + finding's mute status. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.finding.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{name=organizations/*/sources/*/findings/*}:setMute", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{name=organizations/*/sources/*/locations/*/findings/*}:setMute", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{name=folders/*/sources/*/findings/*}:setMute", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{name=folders/*/sources/*/locations/*/findings/*}:setMute", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{name=projects/*/sources/*/findings/*}:setMute", + "body": "*", + }, + { + "method": "post", + "uri": "/v2/{name=projects/*/sources/*/locations/*/findings/*}:setMute", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_set_mute(request, metadata) + pb_request = securitycenter_service.SetMuteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = finding.Finding() + pb_resp = finding.Finding.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_set_mute(resp) + return resp + + class _TestIamPermissions(SecurityCenterRestStub): + def __hash__(self): + return hash("TestIamPermissions") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: iam_policy_pb2.TestIamPermissionsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> iam_policy_pb2.TestIamPermissionsResponse: + r"""Call the test iam permissions method over HTTP. + + Args: + request (~.iam_policy_pb2.TestIamPermissionsRequest): + The request object. Request message for ``TestIamPermissions`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.iam_policy_pb2.TestIamPermissionsResponse: + Response message for ``TestIamPermissions`` method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{resource=organizations/*/sources/*}:testIamPermissions", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_test_iam_permissions( + request, metadata + ) + pb_request = request + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = iam_policy_pb2.TestIamPermissionsResponse() + pb_resp = resp + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_test_iam_permissions(resp) + return resp + + class _UpdateBigQueryExport(SecurityCenterRestStub): + def __hash__(self): + return hash("UpdateBigQueryExport") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.UpdateBigQueryExportRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> bigquery_export.BigQueryExport: + r"""Call the update big query export method over HTTP. + + Args: + request (~.securitycenter_service.UpdateBigQueryExportRequest): + The request object. Request message for updating a + BigQuery export. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.bigquery_export.BigQueryExport: + Configures how to deliver Findings to + BigQuery Instance. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v2/{big_query_export.name=organizations/*/locations/*/bigQueryExports/*}", + "body": "big_query_export", + }, + { + "method": "patch", + "uri": "/v2/{big_query_export.name=folders/*/locations/*/bigQueryExports/*}", + "body": "big_query_export", + }, + { + "method": "patch", + "uri": "/v2/{big_query_export.name=projects/*/locations/*/bigQueryExports/*}", + "body": "big_query_export", + }, + ] + request, metadata = self._interceptor.pre_update_big_query_export( + request, metadata + ) + pb_request = securitycenter_service.UpdateBigQueryExportRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = bigquery_export.BigQueryExport() + pb_resp = bigquery_export.BigQueryExport.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_big_query_export(resp) + return resp + + class _UpdateExternalSystem(SecurityCenterRestStub): + def __hash__(self): + return hash("UpdateExternalSystem") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.UpdateExternalSystemRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_external_system.ExternalSystem: + r"""Call the update external system method over HTTP. + + Args: + request (~.securitycenter_service.UpdateExternalSystemRequest): + The request object. Request message for updating a + ExternalSystem resource. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_external_system.ExternalSystem: + Representation of third party + SIEM/SOAR fields within SCC. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v2/{external_system.name=organizations/*/sources/*/findings/*/externalSystems/*}", + "body": "external_system", + }, + { + "method": "patch", + "uri": "/v2/{external_system.name=organizations/*/sources/*/locations/*/findings/*/externalSystems/*}", + "body": "external_system", + }, + { + "method": "patch", + "uri": "/v2/{external_system.name=folders/*/sources/*/findings/*/externalSystems/*}", + "body": "external_system", + }, + { + "method": "patch", + "uri": "/v2/{external_system.name=folders/*/sources/*/locations/*/findings/*/externalSystems/*}", + "body": "external_system", + }, + { + "method": "patch", + "uri": "/v2/{external_system.name=projects/*/sources/*/findings/*/externalSystems/*}", + "body": "external_system", + }, + { + "method": "patch", + "uri": "/v2/{external_system.name=projects/*/sources/*/locations/*/findings/*/externalSystems/*}", + "body": "external_system", + }, + ] + request, metadata = self._interceptor.pre_update_external_system( + request, metadata + ) + pb_request = securitycenter_service.UpdateExternalSystemRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_external_system.ExternalSystem() + pb_resp = gcs_external_system.ExternalSystem.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_external_system(resp) + return resp + + class _UpdateFinding(SecurityCenterRestStub): + def __hash__(self): + return hash("UpdateFinding") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.UpdateFindingRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_finding.Finding: + r"""Call the update finding method over HTTP. + + Args: + request (~.securitycenter_service.UpdateFindingRequest): + The request object. Request message for updating or + creating a finding. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_finding.Finding: + Security Command Center finding. + + A finding is a record of assessment data + like security, risk, health, or privacy, + that is ingested into Security Command + Center for presentation, notification, + analysis, policy testing, and + enforcement. For example, a cross-site + scripting (XSS) vulnerability in an App + Engine application is a finding. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v2/{finding.name=organizations/*/sources/*/findings/*}", + "body": "finding", + }, + { + "method": "patch", + "uri": "/v2/{finding.name=organizations/*/sources/*/locations/*/findings/*}", + "body": "finding", + }, + { + "method": "patch", + "uri": "/v2/{finding.name=folders/*/sources/*/findings/*}", + "body": "finding", + }, + { + "method": "patch", + "uri": "/v2/{finding.name=folders/*/sources/*/locations/*/findings/*}", + "body": "finding", + }, + { + "method": "patch", + "uri": "/v2/{finding.name=projects/*/sources/*/findings/*}", + "body": "finding", + }, + { + "method": "patch", + "uri": "/v2/{finding.name=projects/*/sources/*/locations/*/findings/*}", + "body": "finding", + }, + ] + request, metadata = self._interceptor.pre_update_finding(request, metadata) + pb_request = securitycenter_service.UpdateFindingRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_finding.Finding() + pb_resp = gcs_finding.Finding.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_finding(resp) + return resp + + class _UpdateMuteConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("UpdateMuteConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.UpdateMuteConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_mute_config.MuteConfig: + r"""Call the update mute config method over HTTP. + + Args: + request (~.securitycenter_service.UpdateMuteConfigRequest): + The request object. Request message for updating a mute + config. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_mute_config.MuteConfig: + A mute config is a Cloud SCC resource + that contains the configuration to mute + create/update events of findings. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v2/{mute_config.name=organizations/*/muteConfigs/*}", + "body": "mute_config", + }, + { + "method": "patch", + "uri": "/v2/{mute_config.name=organizations/*/locations/*/muteConfigs/*}", + "body": "mute_config", + }, + { + "method": "patch", + "uri": "/v2/{mute_config.name=folders/*/muteConfigs/*}", + "body": "mute_config", + }, + { + "method": "patch", + "uri": "/v2/{mute_config.name=folders/*/locations/*/muteConfigs/*}", + "body": "mute_config", + }, + { + "method": "patch", + "uri": "/v2/{mute_config.name=projects/*/muteConfigs/*}", + "body": "mute_config", + }, + { + "method": "patch", + "uri": "/v2/{mute_config.name=projects/*/locations/*/muteConfigs/*}", + "body": "mute_config", + }, + ] + request, metadata = self._interceptor.pre_update_mute_config( + request, metadata + ) + pb_request = securitycenter_service.UpdateMuteConfigRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_mute_config.MuteConfig() + pb_resp = gcs_mute_config.MuteConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_mute_config(resp) + return resp + + class _UpdateNotificationConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("UpdateNotificationConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.UpdateNotificationConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_notification_config.NotificationConfig: + r"""Call the update notification + config method over HTTP. + + Args: + request (~.securitycenter_service.UpdateNotificationConfigRequest): + The request object. Request message for updating a + notification config. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_notification_config.NotificationConfig: + Cloud Security Command Center (Cloud + SCC) notification configs. + A notification config is a Cloud SCC + resource that contains the configuration + to send notifications for create/update + events of findings, assets and etc. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v2/{notification_config.name=organizations/*/locations/*/notificationConfigs/*}", + "body": "notification_config", + }, + { + "method": "patch", + "uri": "/v2/{notification_config.name=folders/*/locations/*/notificationConfigs/*}", + "body": "notification_config", + }, + { + "method": "patch", + "uri": "/v2/{notification_config.name=projects/*/locations/*/notificationConfigs/*}", + "body": "notification_config", + }, + ] + request, metadata = self._interceptor.pre_update_notification_config( + request, metadata + ) + pb_request = securitycenter_service.UpdateNotificationConfigRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_notification_config.NotificationConfig() + pb_resp = gcs_notification_config.NotificationConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_notification_config(resp) + return resp + + class _UpdateResourceValueConfig(SecurityCenterRestStub): + def __hash__(self): + return hash("UpdateResourceValueConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.UpdateResourceValueConfigRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_resource_value_config.ResourceValueConfig: + r"""Call the update resource value + config method over HTTP. + + Args: + request (~.securitycenter_service.UpdateResourceValueConfigRequest): + The request object. Request message to update resource + value config + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_resource_value_config.ResourceValueConfig: + A resource value config (RVC) is a + mapping configuration of user's + resources to resource values. Used in + Attack path simulations. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v2/{resource_value_config.name=organizations/*/resourceValueConfigs/*}", + "body": "resource_value_config", + }, + ] + request, metadata = self._interceptor.pre_update_resource_value_config( + request, metadata + ) + pb_request = securitycenter_service.UpdateResourceValueConfigRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_resource_value_config.ResourceValueConfig() + pb_resp = gcs_resource_value_config.ResourceValueConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_resource_value_config(resp) + return resp + + class _UpdateSecurityMarks(SecurityCenterRestStub): + def __hash__(self): + return hash("UpdateSecurityMarks") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.UpdateSecurityMarksRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_security_marks.SecurityMarks: + r"""Call the update security marks method over HTTP. + + Args: + request (~.securitycenter_service.UpdateSecurityMarksRequest): + The request object. Request message for updating a + SecurityMarks resource. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_security_marks.SecurityMarks: + User specified security marks that + are attached to the parent Security + Command Center resource. Security marks + are scoped within a Security Command + Center organization -- they can be + modified and viewed by all users who + have proper permissions on the + organization. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v2/{security_marks.name=organizations/*/sources/*/findings/*/securityMarks}", + "body": "security_marks", + }, + { + "method": "patch", + "uri": "/v2/{security_marks.name=organizations/*/assets/*/securityMarks}", + "body": "security_marks", + }, + { + "method": "patch", + "uri": "/v2/{security_marks.name=organizations/*/sources/*/locations/*/findings/*/securityMarks}", + "body": "security_marks", + }, + { + "method": "patch", + "uri": "/v2/{security_marks.name=folders/*/sources/*/findings/*/securityMarks}", + "body": "security_marks", + }, + { + "method": "patch", + "uri": "/v2/{security_marks.name=folders/*/assets/*/securityMarks}", + "body": "security_marks", + }, + { + "method": "patch", + "uri": "/v2/{security_marks.name=folders/*/sources/*/locations/*/findings/*/securityMarks}", + "body": "security_marks", + }, + { + "method": "patch", + "uri": "/v2/{security_marks.name=projects/*/sources/*/findings/*/securityMarks}", + "body": "security_marks", + }, + { + "method": "patch", + "uri": "/v2/{security_marks.name=projects/*/assets/*/securityMarks}", + "body": "security_marks", + }, + { + "method": "patch", + "uri": "/v2/{security_marks.name=projects/*/sources/*/locations/*/findings/*/securityMarks}", + "body": "security_marks", + }, + ] + request, metadata = self._interceptor.pre_update_security_marks( + request, metadata + ) + pb_request = securitycenter_service.UpdateSecurityMarksRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_security_marks.SecurityMarks() + pb_resp = gcs_security_marks.SecurityMarks.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_security_marks(resp) + return resp + + class _UpdateSource(SecurityCenterRestStub): + def __hash__(self): + return hash("UpdateSource") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: securitycenter_service.UpdateSourceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcs_source.Source: + r"""Call the update source method over HTTP. + + Args: + request (~.securitycenter_service.UpdateSourceRequest): + The request object. Request message for updating a + source. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.gcs_source.Source: + Security Command Center finding + source. A finding source is an entity or + a mechanism that can produce a finding. + A source is like a container of findings + that come from the same scanner, logger, + monitor, and other tools. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v2/{source.name=organizations/*/sources/*}", + "body": "source", + }, + ] + request, metadata = self._interceptor.pre_update_source(request, metadata) + pb_request = securitycenter_service.UpdateSourceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcs_source.Source() + pb_resp = gcs_source.Source.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_source(resp) + return resp + + @property + def batch_create_resource_value_configs( + self, + ) -> Callable[ + [securitycenter_service.BatchCreateResourceValueConfigsRequest], + securitycenter_service.BatchCreateResourceValueConfigsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchCreateResourceValueConfigs(self._session, self._host, self._interceptor) # type: ignore + + @property + def bulk_mute_findings( + self, + ) -> Callable[ + [securitycenter_service.BulkMuteFindingsRequest], operations_pb2.Operation + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BulkMuteFindings(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.CreateBigQueryExportRequest], + bigquery_export.BigQueryExport, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateBigQueryExport(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_finding( + self, + ) -> Callable[[securitycenter_service.CreateFindingRequest], gcs_finding.Finding]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateFinding(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_mute_config( + self, + ) -> Callable[ + [securitycenter_service.CreateMuteConfigRequest], gcs_mute_config.MuteConfig + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateMuteConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_notification_config( + self, + ) -> Callable[ + [securitycenter_service.CreateNotificationConfigRequest], + gcs_notification_config.NotificationConfig, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateNotificationConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_source( + self, + ) -> Callable[[securitycenter_service.CreateSourceRequest], gcs_source.Source]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateSource(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.DeleteBigQueryExportRequest], empty_pb2.Empty + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteBigQueryExport(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_mute_config( + self, + ) -> Callable[[securitycenter_service.DeleteMuteConfigRequest], empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteMuteConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_notification_config( + self, + ) -> Callable[ + [securitycenter_service.DeleteNotificationConfigRequest], empty_pb2.Empty + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteNotificationConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.DeleteResourceValueConfigRequest], empty_pb2.Empty + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteResourceValueConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.GetBigQueryExportRequest], + bigquery_export.BigQueryExport, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetBigQueryExport(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_iam_policy( + self, + ) -> Callable[[iam_policy_pb2.GetIamPolicyRequest], policy_pb2.Policy]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetIamPolicy(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_mute_config( + self, + ) -> Callable[ + [securitycenter_service.GetMuteConfigRequest], mute_config.MuteConfig + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetMuteConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_notification_config( + self, + ) -> Callable[ + [securitycenter_service.GetNotificationConfigRequest], + notification_config.NotificationConfig, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetNotificationConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.GetResourceValueConfigRequest], + resource_value_config.ResourceValueConfig, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetResourceValueConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_simulation( + self, + ) -> Callable[[securitycenter_service.GetSimulationRequest], simulation.Simulation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetSimulation(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_source( + self, + ) -> Callable[[securitycenter_service.GetSourceRequest], source.Source]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetSource(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_valued_resource( + self, + ) -> Callable[ + [securitycenter_service.GetValuedResourceRequest], + valued_resource.ValuedResource, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetValuedResource(self._session, self._host, self._interceptor) # type: ignore + + @property + def group_findings( + self, + ) -> Callable[ + [securitycenter_service.GroupFindingsRequest], + securitycenter_service.GroupFindingsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GroupFindings(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_attack_paths( + self, + ) -> Callable[ + [securitycenter_service.ListAttackPathsRequest], + securitycenter_service.ListAttackPathsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListAttackPaths(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_big_query_exports( + self, + ) -> Callable[ + [securitycenter_service.ListBigQueryExportsRequest], + securitycenter_service.ListBigQueryExportsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListBigQueryExports(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_findings( + self, + ) -> Callable[ + [securitycenter_service.ListFindingsRequest], + securitycenter_service.ListFindingsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListFindings(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_mute_configs( + self, + ) -> Callable[ + [securitycenter_service.ListMuteConfigsRequest], + securitycenter_service.ListMuteConfigsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListMuteConfigs(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_notification_configs( + self, + ) -> Callable[ + [securitycenter_service.ListNotificationConfigsRequest], + securitycenter_service.ListNotificationConfigsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListNotificationConfigs(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_resource_value_configs( + self, + ) -> Callable[ + [securitycenter_service.ListResourceValueConfigsRequest], + securitycenter_service.ListResourceValueConfigsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListResourceValueConfigs(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_sources( + self, + ) -> Callable[ + [securitycenter_service.ListSourcesRequest], + securitycenter_service.ListSourcesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListSources(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_valued_resources( + self, + ) -> Callable[ + [securitycenter_service.ListValuedResourcesRequest], + securitycenter_service.ListValuedResourcesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListValuedResources(self._session, self._host, self._interceptor) # type: ignore + + @property + def set_finding_state( + self, + ) -> Callable[[securitycenter_service.SetFindingStateRequest], finding.Finding]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._SetFindingState(self._session, self._host, self._interceptor) # type: ignore + + @property + def set_iam_policy( + self, + ) -> Callable[[iam_policy_pb2.SetIamPolicyRequest], policy_pb2.Policy]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._SetIamPolicy(self._session, self._host, self._interceptor) # type: ignore + + @property + def set_mute( + self, + ) -> Callable[[securitycenter_service.SetMuteRequest], finding.Finding]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._SetMute(self._session, self._host, self._interceptor) # type: ignore + + @property + def test_iam_permissions( + self, + ) -> Callable[ + [iam_policy_pb2.TestIamPermissionsRequest], + iam_policy_pb2.TestIamPermissionsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._TestIamPermissions(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_big_query_export( + self, + ) -> Callable[ + [securitycenter_service.UpdateBigQueryExportRequest], + bigquery_export.BigQueryExport, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateBigQueryExport(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_external_system( + self, + ) -> Callable[ + [securitycenter_service.UpdateExternalSystemRequest], + gcs_external_system.ExternalSystem, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateExternalSystem(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_finding( + self, + ) -> Callable[[securitycenter_service.UpdateFindingRequest], gcs_finding.Finding]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateFinding(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_mute_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateMuteConfigRequest], gcs_mute_config.MuteConfig + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateMuteConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_notification_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateNotificationConfigRequest], + gcs_notification_config.NotificationConfig, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateNotificationConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_resource_value_config( + self, + ) -> Callable[ + [securitycenter_service.UpdateResourceValueConfigRequest], + gcs_resource_value_config.ResourceValueConfig, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateResourceValueConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_security_marks( + self, + ) -> Callable[ + [securitycenter_service.UpdateSecurityMarksRequest], + gcs_security_marks.SecurityMarks, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateSecurityMarks(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_source( + self, + ) -> Callable[[securitycenter_service.UpdateSourceRequest], gcs_source.Source]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateSource(self._session, self._host, self._interceptor) # type: ignore + + @property + def cancel_operation(self): + return self._CancelOperation(self._session, self._host, self._interceptor) # type: ignore + + class _CancelOperation(SecurityCenterRestStub): + def __call__( + self, + request: operations_pb2.CancelOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Call the cancel operation method over HTTP. + + Args: + request (operations_pb2.CancelOperationRequest): + The request object for CancelOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2/{name=organizations/*/operations/*}:cancel", + }, + ] + + request, metadata = self._interceptor.pre_cancel_operation( + request, metadata + ) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_cancel_operation(None) + + @property + def delete_operation(self): + return self._DeleteOperation(self._session, self._host, self._interceptor) # type: ignore + + class _DeleteOperation(SecurityCenterRestStub): + def __call__( + self, + request: operations_pb2.DeleteOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Call the delete operation method over HTTP. + + Args: + request (operations_pb2.DeleteOperationRequest): + The request object for DeleteOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2/{name=organizations/*/operations/*}", + }, + ] + + request, metadata = self._interceptor.pre_delete_operation( + request, metadata + ) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_delete_operation(None) + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(SecurityCenterRestStub): + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/operations/*}", + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(SecurityCenterRestStub): + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2/{name=organizations/*/operations}", + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("SecurityCenterRestTransport",) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/__init__.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/__init__.py new file mode 100644 index 000000000000..0706730e171e --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/__init__.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from .access import Access, Geolocation, ServiceAccountDelegationInfo +from .application import Application +from .attack_exposure import AttackExposure +from .attack_path import AttackPath +from .backup_disaster_recovery import BackupDisasterRecovery +from .bigquery_export import BigQueryExport +from .cloud_dlp_data_profile import CloudDlpDataProfile +from .cloud_dlp_inspection import CloudDlpInspection +from .compliance import Compliance +from .connection import Connection +from .contact_details import Contact, ContactDetails +from .container import Container +from .database import Database +from .exfiltration import ExfilResource, Exfiltration +from .external_system import ExternalSystem +from .file import File +from .finding import Finding +from .iam_binding import IamBinding +from .indicator import Indicator +from .kernel_rootkit import KernelRootkit +from .kubernetes import Kubernetes +from .label import Label +from .load_balancer import LoadBalancer +from .log_entry import CloudLoggingEntry, LogEntry +from .mitre_attack import MitreAttack +from .mute_config import MuteConfig +from .notification_config import NotificationConfig +from .notification_message import NotificationMessage +from .org_policy import OrgPolicy +from .process import EnvironmentVariable, Process +from .resource import Resource +from .resource_value_config import ResourceValue, ResourceValueConfig +from .security_marks import SecurityMarks +from .security_posture import SecurityPosture +from .securitycenter_service import ( + BatchCreateResourceValueConfigsRequest, + BatchCreateResourceValueConfigsResponse, + BulkMuteFindingsRequest, + BulkMuteFindingsResponse, + CreateBigQueryExportRequest, + CreateFindingRequest, + CreateMuteConfigRequest, + CreateNotificationConfigRequest, + CreateResourceValueConfigRequest, + CreateSourceRequest, + DeleteBigQueryExportRequest, + DeleteMuteConfigRequest, + DeleteNotificationConfigRequest, + DeleteResourceValueConfigRequest, + GetBigQueryExportRequest, + GetMuteConfigRequest, + GetNotificationConfigRequest, + GetResourceValueConfigRequest, + GetSimulationRequest, + GetSourceRequest, + GetValuedResourceRequest, + GroupFindingsRequest, + GroupFindingsResponse, + GroupResult, + ListAttackPathsRequest, + ListAttackPathsResponse, + ListBigQueryExportsRequest, + ListBigQueryExportsResponse, + ListFindingsRequest, + ListFindingsResponse, + ListMuteConfigsRequest, + ListMuteConfigsResponse, + ListNotificationConfigsRequest, + ListNotificationConfigsResponse, + ListResourceValueConfigsRequest, + ListResourceValueConfigsResponse, + ListSourcesRequest, + ListSourcesResponse, + ListValuedResourcesRequest, + ListValuedResourcesResponse, + SetFindingStateRequest, + SetMuteRequest, + UpdateBigQueryExportRequest, + UpdateExternalSystemRequest, + UpdateFindingRequest, + UpdateMuteConfigRequest, + UpdateNotificationConfigRequest, + UpdateResourceValueConfigRequest, + UpdateSecurityMarksRequest, + UpdateSourceRequest, +) +from .simulation import Simulation +from .source import Source +from .valued_resource import ResourceValueConfigMetadata, ValuedResource +from .vulnerability import ( + Cve, + Cvssv3, + Package, + Reference, + SecurityBulletin, + Vulnerability, +) + +__all__ = ( + "Access", + "Geolocation", + "ServiceAccountDelegationInfo", + "Application", + "AttackExposure", + "AttackPath", + "BackupDisasterRecovery", + "BigQueryExport", + "CloudDlpDataProfile", + "CloudDlpInspection", + "Compliance", + "Connection", + "Contact", + "ContactDetails", + "Container", + "Database", + "ExfilResource", + "Exfiltration", + "ExternalSystem", + "File", + "Finding", + "IamBinding", + "Indicator", + "KernelRootkit", + "Kubernetes", + "Label", + "LoadBalancer", + "CloudLoggingEntry", + "LogEntry", + "MitreAttack", + "MuteConfig", + "NotificationConfig", + "NotificationMessage", + "OrgPolicy", + "EnvironmentVariable", + "Process", + "Resource", + "ResourceValueConfig", + "ResourceValue", + "SecurityMarks", + "SecurityPosture", + "BatchCreateResourceValueConfigsRequest", + "BatchCreateResourceValueConfigsResponse", + "BulkMuteFindingsRequest", + "BulkMuteFindingsResponse", + "CreateBigQueryExportRequest", + "CreateFindingRequest", + "CreateMuteConfigRequest", + "CreateNotificationConfigRequest", + "CreateResourceValueConfigRequest", + "CreateSourceRequest", + "DeleteBigQueryExportRequest", + "DeleteMuteConfigRequest", + "DeleteNotificationConfigRequest", + "DeleteResourceValueConfigRequest", + "GetBigQueryExportRequest", + "GetMuteConfigRequest", + "GetNotificationConfigRequest", + "GetResourceValueConfigRequest", + "GetSimulationRequest", + "GetSourceRequest", + "GetValuedResourceRequest", + "GroupFindingsRequest", + "GroupFindingsResponse", + "GroupResult", + "ListAttackPathsRequest", + "ListAttackPathsResponse", + "ListBigQueryExportsRequest", + "ListBigQueryExportsResponse", + "ListFindingsRequest", + "ListFindingsResponse", + "ListMuteConfigsRequest", + "ListMuteConfigsResponse", + "ListNotificationConfigsRequest", + "ListNotificationConfigsResponse", + "ListResourceValueConfigsRequest", + "ListResourceValueConfigsResponse", + "ListSourcesRequest", + "ListSourcesResponse", + "ListValuedResourcesRequest", + "ListValuedResourcesResponse", + "SetFindingStateRequest", + "SetMuteRequest", + "UpdateBigQueryExportRequest", + "UpdateExternalSystemRequest", + "UpdateFindingRequest", + "UpdateMuteConfigRequest", + "UpdateNotificationConfigRequest", + "UpdateResourceValueConfigRequest", + "UpdateSecurityMarksRequest", + "UpdateSourceRequest", + "Simulation", + "Source", + "ResourceValueConfigMetadata", + "ValuedResource", + "Cve", + "Cvssv3", + "Package", + "Reference", + "SecurityBulletin", + "Vulnerability", +) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/access.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/access.py new file mode 100644 index 000000000000..418ca6b034ae --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/access.py @@ -0,0 +1,194 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Access", + "ServiceAccountDelegationInfo", + "Geolocation", + }, +) + + +class Access(proto.Message): + r"""Represents an access event. + + Attributes: + principal_email (str): + Associated email, such as "foo@google.com". + + The email address of the authenticated user or a service + account acting on behalf of a third party principal making + the request. For third party identity callers, the + ``principal_subject`` field is populated instead of this + field. For privacy reasons, the principal email address is + sometimes redacted. For more information, see `Caller + identities in audit + logs `__. + caller_ip (str): + Caller's IP address, such as "1.1.1.1". + caller_ip_geo (google.cloud.securitycenter_v2.types.Geolocation): + The caller IP's geolocation, which identifies + where the call came from. + user_agent_family (str): + Type of user agent associated with the + finding. For example, an operating system shell + or an embedded or standalone application. + user_agent (str): + The caller's user agent string associated + with the finding. + service_name (str): + This is the API service that the service + account made a call to, e.g. + "iam.googleapis.com". + method_name (str): + The method that the service account called, + e.g. "SetIamPolicy". + principal_subject (str): + A string that represents the principal_subject that is + associated with the identity. Unlike ``principal_email``, + ``principal_subject`` supports principals that aren't + associated with email addresses, such as third party + principals. For most identities, the format is + ``principal://iam.googleapis.com/{identity pool name}/subject/{subject}``. + Some GKE identities, such as GKE_WORKLOAD, FREEFORM, and + GKE_HUB_WORKLOAD, still use the legacy format + ``serviceAccount:{identity pool name}[{subject}]``. + service_account_key_name (str): + The name of the service account key that was used to create + or exchange credentials when authenticating the service + account that made the request. This is a scheme-less URI + full resource name. For example: + + "//iam.googleapis.com/projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}/keys/{key}". + service_account_delegation_info (MutableSequence[google.cloud.securitycenter_v2.types.ServiceAccountDelegationInfo]): + The identity delegation history of an authenticated service + account that made the request. The + ``serviceAccountDelegationInfo[]`` object contains + information about the real authorities that try to access + Google Cloud resources by delegating on a service account. + When multiple authorities are present, they are guaranteed + to be sorted based on the original ordering of the identity + delegation events. + user_name (str): + A string that represents a username. The + username provided depends on the type of the + finding and is likely not an IAM principal. For + example, this can be a system username if the + finding is related to a virtual machine, or it + can be an application login username. + """ + + principal_email: str = proto.Field( + proto.STRING, + number=1, + ) + caller_ip: str = proto.Field( + proto.STRING, + number=2, + ) + caller_ip_geo: "Geolocation" = proto.Field( + proto.MESSAGE, + number=3, + message="Geolocation", + ) + user_agent_family: str = proto.Field( + proto.STRING, + number=4, + ) + user_agent: str = proto.Field( + proto.STRING, + number=5, + ) + service_name: str = proto.Field( + proto.STRING, + number=6, + ) + method_name: str = proto.Field( + proto.STRING, + number=7, + ) + principal_subject: str = proto.Field( + proto.STRING, + number=8, + ) + service_account_key_name: str = proto.Field( + proto.STRING, + number=9, + ) + service_account_delegation_info: MutableSequence[ + "ServiceAccountDelegationInfo" + ] = proto.RepeatedField( + proto.MESSAGE, + number=10, + message="ServiceAccountDelegationInfo", + ) + user_name: str = proto.Field( + proto.STRING, + number=11, + ) + + +class ServiceAccountDelegationInfo(proto.Message): + r"""Identity delegation history of an authenticated service + account. + + Attributes: + principal_email (str): + The email address of a Google account. + principal_subject (str): + A string representing the principal_subject associated with + the identity. As compared to ``principal_email``, supports + principals that aren't associated with email addresses, such + as third party principals. For most identities, the format + will be + ``principal://iam.googleapis.com/{identity pool name}/subjects/{subject}`` + except for some GKE identities (GKE_WORKLOAD, FREEFORM, + GKE_HUB_WORKLOAD) that are still in the legacy format + ``serviceAccount:{identity pool name}[{subject}]`` + """ + + principal_email: str = proto.Field( + proto.STRING, + number=1, + ) + principal_subject: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Geolocation(proto.Message): + r"""Represents a geographical location for a given access. + + Attributes: + region_code (str): + A CLDR. + """ + + region_code: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/application.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/application.py new file mode 100644 index 000000000000..7a6748ca0e1c --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/application.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Application", + }, +) + + +class Application(proto.Message): + r"""Represents an application associated with a finding. + + Attributes: + base_uri (str): + The base URI that identifies the network location of the + application in which the vulnerability was detected. For + example, ``http://example.com``. + full_uri (str): + The full URI with payload that could be used to reproduce + the vulnerability. For example, + ``http://example.com?p=aMmYgI6H``. + """ + + base_uri: str = proto.Field( + proto.STRING, + number=1, + ) + full_uri: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/attack_exposure.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/attack_exposure.py new file mode 100644 index 000000000000..2898db419f1e --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/attack_exposure.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "AttackExposure", + }, +) + + +class AttackExposure(proto.Message): + r"""An attack exposure contains the results of an attack path + simulation run. + + Attributes: + score (float): + A number between 0 (inclusive) and infinity + that represents how important this finding is to + remediate. The higher the score, the more + important it is to remediate. + latest_calculation_time (google.protobuf.timestamp_pb2.Timestamp): + The most recent time the attack exposure was + updated on this finding. + attack_exposure_result (str): + The resource name of the attack path + simulation result that contains the details + regarding this attack exposure score. Example: + organizations/123/simulations/456/attackExposureResults/789 + state (google.cloud.securitycenter_v2.types.AttackExposure.State): + Output only. What state this AttackExposure + is in. This captures whether or not an attack + exposure has been calculated or not. + exposed_high_value_resources_count (int): + The number of high value resources that are + exposed as a result of this finding. + exposed_medium_value_resources_count (int): + The number of medium value resources that are + exposed as a result of this finding. + exposed_low_value_resources_count (int): + The number of high value resources that are + exposed as a result of this finding. + """ + + class State(proto.Enum): + r"""This enum defines the various states an AttackExposure can be + in. + + Values: + STATE_UNSPECIFIED (0): + The state is not specified. + CALCULATED (1): + The attack exposure has been calculated. + NOT_CALCULATED (2): + The attack exposure has not been calculated. + """ + STATE_UNSPECIFIED = 0 + CALCULATED = 1 + NOT_CALCULATED = 2 + + score: float = proto.Field( + proto.DOUBLE, + number=1, + ) + latest_calculation_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + attack_exposure_result: str = proto.Field( + proto.STRING, + number=3, + ) + state: State = proto.Field( + proto.ENUM, + number=4, + enum=State, + ) + exposed_high_value_resources_count: int = proto.Field( + proto.INT32, + number=5, + ) + exposed_medium_value_resources_count: int = proto.Field( + proto.INT32, + number=6, + ) + exposed_low_value_resources_count: int = proto.Field( + proto.INT32, + number=7, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/attack_path.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/attack_path.py new file mode 100644 index 000000000000..e135432c52fd --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/attack_path.py @@ -0,0 +1,228 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "AttackPath", + }, +) + + +class AttackPath(proto.Message): + r"""A path that an attacker could take to reach an exposed + resource. + + Attributes: + name (str): + The attack path name, for example, + ``organizations/12/simulations/34/valuedResources/56/attackPaths/78`` + path_nodes (MutableSequence[google.cloud.securitycenter_v2.types.AttackPath.AttackPathNode]): + A list of nodes that exist in this attack + path. + edges (MutableSequence[google.cloud.securitycenter_v2.types.AttackPath.AttackPathEdge]): + A list of the edges between nodes in this + attack path. + """ + + class AttackPathNode(proto.Message): + r"""Represents one point that an attacker passes through in this + attack path. + + Attributes: + resource (str): + The name of the resource at this point in the attack path. + The format of the name follows the Cloud Asset Inventory + `resource name + format <"https://cloud.google.com/asset-inventory/docs/resource-name-format">`__ + resource_type (str): + The `supported resource + type `__ + display_name (str): + Human-readable name of this resource. + associated_findings (MutableSequence[google.cloud.securitycenter_v2.types.AttackPath.AttackPathNode.PathNodeAssociatedFinding]): + The findings associated with this node in the + attack path. + uuid (str): + Unique id of the attack path node. + attack_steps (MutableSequence[google.cloud.securitycenter_v2.types.AttackPath.AttackPathNode.AttackStepNode]): + A list of attack step nodes that exist in + this attack path node. + """ + + class NodeType(proto.Enum): + r"""The type of the incoming attack step node. + + Values: + NODE_TYPE_UNSPECIFIED (0): + Type not specified + NODE_TYPE_AND (1): + Incoming edge joined with AND + NODE_TYPE_OR (2): + Incoming edge joined with OR + NODE_TYPE_DEFENSE (3): + Incoming edge is defense + NODE_TYPE_ATTACKER (4): + Incoming edge is attacker + """ + NODE_TYPE_UNSPECIFIED = 0 + NODE_TYPE_AND = 1 + NODE_TYPE_OR = 2 + NODE_TYPE_DEFENSE = 3 + NODE_TYPE_ATTACKER = 4 + + class PathNodeAssociatedFinding(proto.Message): + r"""A finding that is associated with this node in the attack + path. + + Attributes: + canonical_finding (str): + Canonical name of the associated findings. + Example: + organizations/123/sources/456/findings/789 + finding_category (str): + The additional taxonomy group within findings + from a given source. + name (str): + Full resource name of the finding. + """ + + canonical_finding: str = proto.Field( + proto.STRING, + number=1, + ) + finding_category: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + + class AttackStepNode(proto.Message): + r"""Detailed steps the attack can take between path nodes. + + Attributes: + uuid (str): + Unique ID for one Node + type_ (google.cloud.securitycenter_v2.types.AttackPath.AttackPathNode.NodeType): + Attack step type. Can be either AND, OR or + DEFENSE + display_name (str): + User friendly name of the attack step + labels (MutableMapping[str, str]): + Attack step labels for metadata + description (str): + Attack step description + """ + + uuid: str = proto.Field( + proto.STRING, + number=1, + ) + type_: "AttackPath.AttackPathNode.NodeType" = proto.Field( + proto.ENUM, + number=2, + enum="AttackPath.AttackPathNode.NodeType", + ) + display_name: str = proto.Field( + proto.STRING, + number=3, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=4, + ) + description: str = proto.Field( + proto.STRING, + number=5, + ) + + resource: str = proto.Field( + proto.STRING, + number=1, + ) + resource_type: str = proto.Field( + proto.STRING, + number=2, + ) + display_name: str = proto.Field( + proto.STRING, + number=3, + ) + associated_findings: MutableSequence[ + "AttackPath.AttackPathNode.PathNodeAssociatedFinding" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="AttackPath.AttackPathNode.PathNodeAssociatedFinding", + ) + uuid: str = proto.Field( + proto.STRING, + number=5, + ) + attack_steps: MutableSequence[ + "AttackPath.AttackPathNode.AttackStepNode" + ] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message="AttackPath.AttackPathNode.AttackStepNode", + ) + + class AttackPathEdge(proto.Message): + r"""Represents a connection between a source node and a + destination node in this attack path. + + Attributes: + source (str): + The attack node uuid of the source node. + destination (str): + The attack node uuid of the destination node. + """ + + source: str = proto.Field( + proto.STRING, + number=1, + ) + destination: str = proto.Field( + proto.STRING, + number=2, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + path_nodes: MutableSequence[AttackPathNode] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=AttackPathNode, + ) + edges: MutableSequence[AttackPathEdge] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=AttackPathEdge, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/backup_disaster_recovery.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/backup_disaster_recovery.py new file mode 100644 index 000000000000..030737124c9d --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/backup_disaster_recovery.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "BackupDisasterRecovery", + }, +) + + +class BackupDisasterRecovery(proto.Message): + r"""Information related to Google Cloud Backup and DR Service + findings. + + Attributes: + backup_template (str): + The name of a Backup and DR template which comprises one or + more backup policies. See the `Backup and DR + documentation `__ + for more information. For example, ``snap-ov``. + policies (MutableSequence[str]): + The names of Backup and DR policies that are associated with + a template and that define when to run a backup, how + frequently to run a backup, and how long to retain the + backup image. For example, ``onvaults``. + host (str): + The name of a Backup and DR host, which is managed by the + backup and recovery appliance and known to the management + console. The host can be of type Generic (for example, + Compute Engine, SQL Server, Oracle DB, SMB file system, + etc.), vCenter, or an ESX server. See the `Backup and DR + documentation on + hosts `__ + for more information. For example, ``centos7-01``. + applications (MutableSequence[str]): + The names of Backup and DR applications. An application is a + VM, database, or file system on a managed host monitored by + a backup and recovery appliance. For example, + ``centos7-01-vol00``, ``centos7-01-vol01``, + ``centos7-01-vol02``. + storage_pool (str): + The name of the Backup and DR storage pool that the backup + and recovery appliance is storing data in. The storage pool + could be of type Cloud, Primary, Snapshot, or OnVault. See + the `Backup and DR documentation on storage + pools `__. + For example, ``DiskPoolOne``. + policy_options (MutableSequence[str]): + The names of Backup and DR advanced policy options of a + policy applying to an application. See the `Backup and DR + documentation on policy + options `__. + For example, ``skipofflineappsincongrp, nounmap``. + profile (str): + The name of the Backup and DR resource profile that + specifies the storage media for backups of application and + VM data. See the `Backup and DR documentation on + profiles `__. + For example, ``GCP``. + appliance (str): + The name of the Backup and DR appliance that captures, + moves, and manages the lifecycle of backup data. For + example, ``backup-server-57137``. + backup_type (str): + The backup type of the Backup and DR image. For example, + ``Snapshot``, ``Remote Snapshot``, ``OnVault``. + backup_create_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp at which the Backup and DR + backup was created. + """ + + backup_template: str = proto.Field( + proto.STRING, + number=1, + ) + policies: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + host: str = proto.Field( + proto.STRING, + number=3, + ) + applications: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + storage_pool: str = proto.Field( + proto.STRING, + number=5, + ) + policy_options: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=6, + ) + profile: str = proto.Field( + proto.STRING, + number=7, + ) + appliance: str = proto.Field( + proto.STRING, + number=8, + ) + backup_type: str = proto.Field( + proto.STRING, + number=9, + ) + backup_create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=10, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/bigquery_export.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/bigquery_export.py new file mode 100644 index 000000000000..d935d7b328fa --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/bigquery_export.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "BigQueryExport", + }, +) + + +class BigQueryExport(proto.Message): + r"""Configures how to deliver Findings to BigQuery Instance. + + Attributes: + name (str): + The relative resource name of this export. See: + https://cloud.google.com/apis/design/resource_names#relative_resource_name. + The following list shows some examples: + + - + + ``organizations/{organization_id}/locations/{location_id}/bigQueryExports/{export_id}`` + + - ``folders/{folder_id}/locations/{location_id}/bigQueryExports/{export_id}`` + - + + ``projects/{project_id}/locations/{location_id}/bigQueryExports/{export_id}`` + + This field is provided in responses, and is ignored when + provided in create requests. + description (str): + The description of the export (max of 1024 + characters). + filter (str): + Expression that defines the filter to apply across + create/update events of findings. The expression is a list + of zero or more restrictions combined via logical operators + ``AND`` and ``OR``. Parentheses are supported, and ``OR`` + has higher precedence than ``AND``. + + Restrictions have the form `` `` + and may have a ``-`` character in front of them to indicate + negation. The fields map to those defined in the + corresponding resource. + + The supported operators are: + + - ``=`` for all value types. + - ``>``, ``<``, ``>=``, ``<=`` for integer values. + - ``:``, meaning substring matching, for strings. + + The supported value types are: + + - string literals in quotes. + - integer literals without quotes. + - boolean literals ``true`` and ``false`` without quotes. + dataset (str): + The dataset to write findings' updates to. Its format is + "projects/[project_id]/datasets/[bigquery_dataset_id]". + BigQuery Dataset unique ID must contain only letters (a-z, + A-Z), numbers (0-9), or underscores (_). + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time at which the BigQuery + export was created. This field is set by the + server and will be ignored if provided on export + on creation. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The most recent time at which + the BigQuery export was updated. This field is + set by the server and will be ignored if + provided on export creation or update. + most_recent_editor (str): + Output only. Email address of the user who + last edited the BigQuery export. This field is + set by the server and will be ignored if + provided on export creation or update. + principal (str): + Output only. The service account that needs + permission to create table and upload data to + the BigQuery dataset. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + filter: str = proto.Field( + proto.STRING, + number=3, + ) + dataset: str = proto.Field( + proto.STRING, + number=4, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + most_recent_editor: str = proto.Field( + proto.STRING, + number=7, + ) + principal: str = proto.Field( + proto.STRING, + number=8, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/cloud_dlp_data_profile.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/cloud_dlp_data_profile.py new file mode 100644 index 000000000000..52f9e4b253a0 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/cloud_dlp_data_profile.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "CloudDlpDataProfile", + }, +) + + +class CloudDlpDataProfile(proto.Message): + r"""The `data + profile `__ + associated with the finding. + + Attributes: + data_profile (str): + Name of the data profile, for example, + ``projects/123/locations/europe/tableProfiles/8383929``. + parent_type (google.cloud.securitycenter_v2.types.CloudDlpDataProfile.ParentType): + The resource hierarchy level at which the + data profile was generated. + """ + + class ParentType(proto.Enum): + r"""Parents for configurations that produce data profile + findings. + + Values: + PARENT_TYPE_UNSPECIFIED (0): + Unspecified parent type. + ORGANIZATION (1): + Organization-level configurations. + PROJECT (2): + Project-level configurations. + """ + PARENT_TYPE_UNSPECIFIED = 0 + ORGANIZATION = 1 + PROJECT = 2 + + data_profile: str = proto.Field( + proto.STRING, + number=1, + ) + parent_type: ParentType = proto.Field( + proto.ENUM, + number=2, + enum=ParentType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/cloud_dlp_inspection.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/cloud_dlp_inspection.py new file mode 100644 index 000000000000..bb19bcf8fda1 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/cloud_dlp_inspection.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "CloudDlpInspection", + }, +) + + +class CloudDlpInspection(proto.Message): + r"""Details about the Cloud Data Loss Prevention (Cloud DLP) `inspection + job `__ + that produced the finding. + + Attributes: + inspect_job (str): + Name of the inspection job, for example, + ``projects/123/locations/europe/dlpJobs/i-8383929``. + info_type (str): + The type of information (or + `infoType `__) + found, for example, ``EMAIL_ADDRESS`` or ``STREET_ADDRESS``. + info_type_count (int): + The number of times Cloud DLP found this + infoType within this job and resource. + full_scan (bool): + Whether Cloud DLP scanned the complete + resource or a sampled subset. + """ + + inspect_job: str = proto.Field( + proto.STRING, + number=1, + ) + info_type: str = proto.Field( + proto.STRING, + number=2, + ) + info_type_count: int = proto.Field( + proto.INT64, + number=3, + ) + full_scan: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/compliance.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/compliance.py new file mode 100644 index 000000000000..7b0445ed2401 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/compliance.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Compliance", + }, +) + + +class Compliance(proto.Message): + r"""Contains compliance information about a security standard + indicating unmet recommendations. + + Attributes: + standard (str): + Industry-wide compliance standards or + benchmarks, such as CIS, PCI, and OWASP. + version (str): + Version of the standard or benchmark, for + example, 1.1 + ids (MutableSequence[str]): + Policies within the standard or benchmark, + for example, A.12.4.1 + """ + + standard: str = proto.Field( + proto.STRING, + number=1, + ) + version: str = proto.Field( + proto.STRING, + number=2, + ) + ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/connection.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/connection.py new file mode 100644 index 000000000000..d95619f1946f --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/connection.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Connection", + }, +) + + +class Connection(proto.Message): + r"""Contains information about the IP connection associated with + the finding. + + Attributes: + destination_ip (str): + Destination IP address. Not present for + sockets that are listening and not connected. + destination_port (int): + Destination port. Not present for sockets + that are listening and not connected. + source_ip (str): + Source IP address. + source_port (int): + Source port. + protocol (google.cloud.securitycenter_v2.types.Connection.Protocol): + IANA Internet Protocol Number such as TCP(6) + and UDP(17). + """ + + class Protocol(proto.Enum): + r"""IANA Internet Protocol Number such as TCP(6) and UDP(17). + + Values: + PROTOCOL_UNSPECIFIED (0): + Unspecified protocol (not HOPOPT). + ICMP (1): + Internet Control Message Protocol. + TCP (6): + Transmission Control Protocol. + UDP (17): + User Datagram Protocol. + GRE (47): + Generic Routing Encapsulation. + ESP (50): + Encap Security Payload. + """ + PROTOCOL_UNSPECIFIED = 0 + ICMP = 1 + TCP = 6 + UDP = 17 + GRE = 47 + ESP = 50 + + destination_ip: str = proto.Field( + proto.STRING, + number=1, + ) + destination_port: int = proto.Field( + proto.INT32, + number=2, + ) + source_ip: str = proto.Field( + proto.STRING, + number=3, + ) + source_port: int = proto.Field( + proto.INT32, + number=4, + ) + protocol: Protocol = proto.Field( + proto.ENUM, + number=5, + enum=Protocol, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/contact_details.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/contact_details.py new file mode 100644 index 000000000000..43479810fcd8 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/contact_details.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "ContactDetails", + "Contact", + }, +) + + +class ContactDetails(proto.Message): + r"""Details about specific contacts + + Attributes: + contacts (MutableSequence[google.cloud.securitycenter_v2.types.Contact]): + A list of contacts + """ + + contacts: MutableSequence["Contact"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Contact", + ) + + +class Contact(proto.Message): + r"""The email address of a contact. + + Attributes: + email (str): + An email address. For example, "``person123@company.com``". + """ + + email: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/container.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/container.py new file mode 100644 index 000000000000..a9c057dfec3d --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/container.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +from google.cloud.securitycenter_v2.types import label + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Container", + }, +) + + +class Container(proto.Message): + r"""Container associated with the finding. + + Attributes: + name (str): + Name of the container. + uri (str): + Container image URI provided when configuring + a pod or container. This string can identify a + container image version using mutable tags. + image_id (str): + Optional container image ID, if provided by + the container runtime. Uniquely identifies the + container image launched using a container image + digest. + labels (MutableSequence[google.cloud.securitycenter_v2.types.Label]): + Container labels, as provided by the + container runtime. + create_time (google.protobuf.timestamp_pb2.Timestamp): + The time that the container was created. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + uri: str = proto.Field( + proto.STRING, + number=2, + ) + image_id: str = proto.Field( + proto.STRING, + number=3, + ) + labels: MutableSequence[label.Label] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=label.Label, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/database.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/database.py new file mode 100644 index 000000000000..c6e72495b397 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/database.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Database", + }, +) + + +class Database(proto.Message): + r"""Represents database access information, such as queries. A database + may be a sub-resource of an instance (as in the case of Cloud SQL + instances or Cloud Spanner instances), or the database instance + itself. Some database resources might not have the `full resource + name `__ populated + because these resource types, such as Cloud SQL databases, are not + yet supported by Cloud Asset Inventory. In these cases only the + display name is provided. + + Attributes: + name (str): + Some database resources may not have the `full resource + name `__ + populated because these resource types are not yet supported + by Cloud Asset Inventory (e.g. Cloud SQL databases). In + these cases only the display name will be provided. The + `full resource + name `__ of + the database that the user connected to, if it is supported + by Cloud Asset Inventory. + display_name (str): + The human-readable name of the database that + the user connected to. + user_name (str): + The username used to connect to the database. + The username might not be an IAM principal and + does not have a set format. + query (str): + The SQL statement that is associated with the + database access. + grantees (MutableSequence[str]): + The target usernames, roles, or groups of an + SQL privilege grant, which is not an IAM policy + change. + version (str): + The version of the database, for example, POSTGRES_14. See + `the complete + list `__. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + user_name: str = proto.Field( + proto.STRING, + number=3, + ) + query: str = proto.Field( + proto.STRING, + number=4, + ) + grantees: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + version: str = proto.Field( + proto.STRING, + number=6, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/exfiltration.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/exfiltration.py new file mode 100644 index 000000000000..14f08452b2d2 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/exfiltration.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Exfiltration", + "ExfilResource", + }, +) + + +class Exfiltration(proto.Message): + r"""Exfiltration represents a data exfiltration attempt from one or more + sources to one or more targets. The ``sources`` attribute lists the + sources of the exfiltrated data. The ``targets`` attribute lists the + destinations the data was copied to. + + Attributes: + sources (MutableSequence[google.cloud.securitycenter_v2.types.ExfilResource]): + If there are multiple sources, then the data + is considered "joined" between them. For + instance, BigQuery can join multiple tables, and + each table would be considered a source. + targets (MutableSequence[google.cloud.securitycenter_v2.types.ExfilResource]): + If there are multiple targets, each target + would get a complete copy of the "joined" source + data. + total_exfiltrated_bytes (int): + Total exfiltrated bytes processed for the + entire job. + """ + + sources: MutableSequence["ExfilResource"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="ExfilResource", + ) + targets: MutableSequence["ExfilResource"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="ExfilResource", + ) + total_exfiltrated_bytes: int = proto.Field( + proto.INT64, + number=3, + ) + + +class ExfilResource(proto.Message): + r"""Resource where data was exfiltrated from or exfiltrated to. + + Attributes: + name (str): + The resource's `full resource + name `__. + components (MutableSequence[str]): + Subcomponents of the asset that was + exfiltrated, like URIs used during exfiltration, + table names, databases, and filenames. For + example, multiple tables might have been + exfiltrated from the same Cloud SQL instance, or + multiple files might have been exfiltrated from + the same Cloud Storage bucket. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + components: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/external_system.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/external_system.py new file mode 100644 index 000000000000..e6e763323267 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/external_system.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "ExternalSystem", + }, +) + + +class ExternalSystem(proto.Message): + r"""Representation of third party SIEM/SOAR fields within SCC. + + Attributes: + name (str): + Full resource name of the external system. The following + list shows some examples: + + - ``organizations/1234/sources/5678/findings/123456/externalSystems/jira`` + - + + ``organizations/1234/sources/5678/locations/us/findings/123456/externalSystems/jira`` + + - ``folders/1234/sources/5678/findings/123456/externalSystems/jira`` + - + + ``folders/1234/sources/5678/locations/us/findings/123456/externalSystems/jira`` + + - ``projects/1234/sources/5678/findings/123456/externalSystems/jira`` + - + + ``projects/1234/sources/5678/locations/us/findings/123456/externalSystems/jira`` + assignees (MutableSequence[str]): + References primary/secondary etc assignees in + the external system. + external_uid (str): + The identifier that's used to track the + finding's corresponding case in the external + system. + status (str): + The most recent status of the finding's + corresponding case, as reported by the external + system. + external_system_update_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the case was last updated, as + reported by the external system. + case_uri (str): + The link to the finding's corresponding case + in the external system. + case_priority (str): + The priority of the finding's corresponding + case in the external system. + case_sla (google.protobuf.timestamp_pb2.Timestamp): + The SLA of the finding's corresponding case + in the external system. + case_create_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the case was created, as + reported by the external system. + case_close_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the case was closed, as + reported by the external system. + ticket_info (google.cloud.securitycenter_v2.types.ExternalSystem.TicketInfo): + Information about the ticket, if any, that is + being used to track the resolution of the issue + that is identified by this finding. + """ + + class TicketInfo(proto.Message): + r"""Information about the ticket, if any, that is being used to + track the resolution of the issue that is identified by this + finding. + + Attributes: + id (str): + The identifier of the ticket in the ticket + system. + assignee (str): + The assignee of the ticket in the ticket + system. + description (str): + The description of the ticket in the ticket + system. + uri (str): + The link to the ticket in the ticket system. + status (str): + The latest status of the ticket, as reported + by the ticket system. + update_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the ticket was last updated, as + reported by the ticket system. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + assignee: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + uri: str = proto.Field( + proto.STRING, + number=4, + ) + status: str = proto.Field( + proto.STRING, + number=5, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + assignees: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + external_uid: str = proto.Field( + proto.STRING, + number=3, + ) + status: str = proto.Field( + proto.STRING, + number=4, + ) + external_system_update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + case_uri: str = proto.Field( + proto.STRING, + number=6, + ) + case_priority: str = proto.Field( + proto.STRING, + number=7, + ) + case_sla: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=9, + message=timestamp_pb2.Timestamp, + ) + case_create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=10, + message=timestamp_pb2.Timestamp, + ) + case_close_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=11, + message=timestamp_pb2.Timestamp, + ) + ticket_info: TicketInfo = proto.Field( + proto.MESSAGE, + number=8, + message=TicketInfo, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/file.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/file.py new file mode 100644 index 000000000000..b68b00daead0 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/file.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "File", + }, +) + + +class File(proto.Message): + r"""File information about the related binary/library used by an + executable, or the script used by a script interpreter + + Attributes: + path (str): + Absolute path of the file as a JSON encoded + string. + size (int): + Size of the file in bytes. + sha256 (str): + SHA256 hash of the first hashed_size bytes of the file + encoded as a hex string. If hashed_size == size, sha256 + represents the SHA256 hash of the entire file. + hashed_size (int): + The length in bytes of the file prefix that was hashed. If + hashed_size == size, any hashes reported represent the + entire file. + partially_hashed (bool): + True when the hash covers only a prefix of + the file. + contents (str): + Prefix of the file contents as a JSON-encoded + string. + disk_path (google.cloud.securitycenter_v2.types.File.DiskPath): + Path of the file in terms of underlying + disk/partition identifiers. + """ + + class DiskPath(proto.Message): + r"""Path of the file in terms of underlying disk/partition + identifiers. + + Attributes: + partition_uuid (str): + UUID of the partition (format + https://wiki.archlinux.org/title/persistent_block_device_naming#by-uuid) + relative_path (str): + Relative path of the file in the partition as a JSON encoded + string. Example: /home/user1/executable_file.sh + """ + + partition_uuid: str = proto.Field( + proto.STRING, + number=1, + ) + relative_path: str = proto.Field( + proto.STRING, + number=2, + ) + + path: str = proto.Field( + proto.STRING, + number=1, + ) + size: int = proto.Field( + proto.INT64, + number=2, + ) + sha256: str = proto.Field( + proto.STRING, + number=3, + ) + hashed_size: int = proto.Field( + proto.INT64, + number=4, + ) + partially_hashed: bool = proto.Field( + proto.BOOL, + number=5, + ) + contents: str = proto.Field( + proto.STRING, + number=6, + ) + disk_path: DiskPath = proto.Field( + proto.MESSAGE, + number=7, + message=DiskPath, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/finding.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/finding.py new file mode 100644 index 000000000000..00d19bc2ab25 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/finding.py @@ -0,0 +1,690 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +from google.cloud.securitycenter_v2.types import ( + compliance, + connection, + contact_details, + container, +) +from google.cloud.securitycenter_v2.types import external_system, file, iam_binding +from google.cloud.securitycenter_v2.types import attack_exposure as gcs_attack_exposure +from google.cloud.securitycenter_v2.types import ( + backup_disaster_recovery as gcs_backup_disaster_recovery, +) +from google.cloud.securitycenter_v2.types import ( + cloud_dlp_data_profile as gcs_cloud_dlp_data_profile, +) +from google.cloud.securitycenter_v2.types import ( + cloud_dlp_inspection as gcs_cloud_dlp_inspection, +) +from google.cloud.securitycenter_v2.types import exfiltration as gcs_exfiltration +from google.cloud.securitycenter_v2.types import kernel_rootkit as gcs_kernel_rootkit +from google.cloud.securitycenter_v2.types import mitre_attack as gcs_mitre_attack +from google.cloud.securitycenter_v2.types import security_marks as gcs_security_marks +from google.cloud.securitycenter_v2.types import ( + security_posture as gcs_security_posture, +) +from google.cloud.securitycenter_v2.types import vulnerability as gcs_vulnerability +from google.cloud.securitycenter_v2.types import access as gcs_access +from google.cloud.securitycenter_v2.types import application as gcs_application +from google.cloud.securitycenter_v2.types import database as gcs_database +from google.cloud.securitycenter_v2.types import indicator as gcs_indicator +from google.cloud.securitycenter_v2.types import kubernetes as gcs_kubernetes +from google.cloud.securitycenter_v2.types import load_balancer, log_entry +from google.cloud.securitycenter_v2.types import org_policy, process + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Finding", + }, +) + + +class Finding(proto.Message): + r"""Security Command Center finding. + + A finding is a record of assessment data like security, risk, + health, or privacy, that is ingested into Security Command + Center for presentation, notification, analysis, policy testing, + and enforcement. For example, a cross-site scripting (XSS) + vulnerability in an App Engine application is a finding. + + Attributes: + name (str): + The `relative resource + name `__ + of the finding. The following list shows some examples: + + - + + ``organizations/{organization_id}/sources/{source_id}/findings/{finding_id}`` + + + ``organizations/{organization_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``folders/{folder_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``folders/{folder_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``projects/{project_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``projects/{project_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + canonical_name (str): + Output only. The canonical name of the finding. The + following list shows some examples: + + - + + ``organizations/{organization_id}/sources/{source_id}/findings/{finding_id}`` + + + ``organizations/{organization_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``folders/{folder_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``folders/{folder_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``projects/{project_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``projects/{project_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + The prefix is the closest CRM ancestor of the resource + associated with the finding. + parent (str): + The relative resource name of the source and location the + finding belongs to. See: + https://cloud.google.com/apis/design/resource_names#relative_resource_name + This field is immutable after creation time. The following + list shows some examples: + + - ``organizations/{organization_id}/sources/{source_id}`` + - ``folders/{folders_id}/sources/{source_id}`` + - ``projects/{projects_id}/sources/{source_id}`` + - + + ``organizations/{organization_id}/sources/{source_id}/locations/{location_id}`` + + - ``folders/{folders_id}/sources/{source_id}/locations/{location_id}`` + - ``projects/{projects_id}/sources/{source_id}/locations/{location_id}`` + resource_name (str): + Immutable. For findings on Google Cloud resources, the full + resource name of the Google Cloud resource this finding is + for. See: + https://cloud.google.com/apis/design/resource_names#full_resource_name + When the finding is for a non-Google Cloud resource, the + resourceName can be a customer or partner defined string. + state (google.cloud.securitycenter_v2.types.Finding.State): + Output only. The state of the finding. + category (str): + Immutable. The additional taxonomy group within findings + from a given source. Example: "XSS_FLASH_INJECTION". + external_uri (str): + The URI that, if available, points to a web + page outside of Security Command Center where + additional information about the finding can be + found. This field is guaranteed to be either + empty or a well formed URL. + source_properties (MutableMapping[str, google.protobuf.struct_pb2.Value]): + Source specific properties. These properties are managed by + the source that writes the finding. The key names in the + source_properties map must be between 1 and 255 characters, + and must start with a letter and contain alphanumeric + characters or underscores only. + security_marks (google.cloud.securitycenter_v2.types.SecurityMarks): + Output only. User specified security marks. + These marks are entirely managed by the user and + come from the SecurityMarks resource that + belongs to the finding. + event_time (google.protobuf.timestamp_pb2.Timestamp): + The time the finding was first detected. If + an existing finding is updated, then this is the + time the update occurred. For example, if the + finding represents an open firewall, this + property captures the time the detector believes + the firewall became open. The accuracy is + determined by the detector. If the finding is + later resolved, then this time reflects when the + finding was resolved. This must not be set to a + value greater than the current timestamp. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time at which the finding + was created in Security Command Center. + severity (google.cloud.securitycenter_v2.types.Finding.Severity): + The severity of the finding. This field is + managed by the source that writes the finding. + mute (google.cloud.securitycenter_v2.types.Finding.Mute): + Indicates the mute state of a finding (either + muted, unmuted or undefined). Unlike other + attributes of a finding, a finding provider + shouldn't set the value of mute. + finding_class (google.cloud.securitycenter_v2.types.Finding.FindingClass): + The class of the finding. + indicator (google.cloud.securitycenter_v2.types.Indicator): + Represents what's commonly known as an *indicator of + compromise* (IoC) in computer forensics. This is an artifact + observed on a network or in an operating system that, with + high confidence, indicates a computer intrusion. For more + information, see `Indicator of + compromise `__. + vulnerability (google.cloud.securitycenter_v2.types.Vulnerability): + Represents vulnerability-specific fields like + CVE and CVSS scores. CVE stands for Common + Vulnerabilities and Exposures + (https://cve.mitre.org/about/) + mute_update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The most recent time this + finding was muted or unmuted. + external_systems (MutableMapping[str, google.cloud.securitycenter_v2.types.ExternalSystem]): + Output only. Third party SIEM/SOAR fields + within SCC, contains external system information + and external system finding fields. + mitre_attack (google.cloud.securitycenter_v2.types.MitreAttack): + MITRE ATT&CK tactics and techniques related + to this finding. See: https://attack.mitre.org + access (google.cloud.securitycenter_v2.types.Access): + Access details associated with the finding, + such as more information on the caller, which + method was accessed, and from where. + connections (MutableSequence[google.cloud.securitycenter_v2.types.Connection]): + Contains information about the IP connection + associated with the finding. + mute_initiator (str): + Records additional information about the mute operation, for + example, the `mute + configuration `__ + that muted the finding and the user who muted the finding. + processes (MutableSequence[google.cloud.securitycenter_v2.types.Process]): + Represents operating system processes + associated with the Finding. + contacts (MutableMapping[str, google.cloud.securitycenter_v2.types.ContactDetails]): + Output only. Map containing the points of contact for the + given finding. The key represents the type of contact, while + the value contains a list of all the contacts that pertain. + Please refer to: + https://cloud.google.com/resource-manager/docs/managing-notification-contacts#notification-categories + + :: + + { + "security": { + "contacts": [ + { + "email": "person1@company.com" + }, + { + "email": "person2@company.com" + } + ] + } + } + compliances (MutableSequence[google.cloud.securitycenter_v2.types.Compliance]): + Contains compliance information for security + standards associated to the finding. + parent_display_name (str): + Output only. The human readable display name + of the finding source such as "Event Threat + Detection" or "Security Health Analytics". + description (str): + Contains more details about the finding. + exfiltration (google.cloud.securitycenter_v2.types.Exfiltration): + Represents exfiltrations associated with the + finding. + iam_bindings (MutableSequence[google.cloud.securitycenter_v2.types.IamBinding]): + Represents IAM bindings associated with the + finding. + next_steps (str): + Steps to address the finding. + module_name (str): + Unique identifier of the module which + generated the finding. Example: + + folders/598186756061/securityHealthAnalyticsSettings/customModules/56799441161885 + containers (MutableSequence[google.cloud.securitycenter_v2.types.Container]): + Containers associated with the finding. This + field provides information for both Kubernetes + and non-Kubernetes containers. + kubernetes (google.cloud.securitycenter_v2.types.Kubernetes): + Kubernetes resources associated with the + finding. + database (google.cloud.securitycenter_v2.types.Database): + Database associated with the finding. + attack_exposure (google.cloud.securitycenter_v2.types.AttackExposure): + The results of an attack path simulation + relevant to this finding. + files (MutableSequence[google.cloud.securitycenter_v2.types.File]): + File associated with the finding. + cloud_dlp_inspection (google.cloud.securitycenter_v2.types.CloudDlpInspection): + Cloud Data Loss Prevention (Cloud DLP) + inspection results that are associated with the + finding. + cloud_dlp_data_profile (google.cloud.securitycenter_v2.types.CloudDlpDataProfile): + Cloud DLP data profile that is associated + with the finding. + kernel_rootkit (google.cloud.securitycenter_v2.types.KernelRootkit): + Signature of the kernel rootkit. + org_policies (MutableSequence[google.cloud.securitycenter_v2.types.OrgPolicy]): + Contains information about the org policies + associated with the finding. + application (google.cloud.securitycenter_v2.types.Application): + Represents an application associated with the + finding. + backup_disaster_recovery (google.cloud.securitycenter_v2.types.BackupDisasterRecovery): + Fields related to Backup and DR findings. + security_posture (google.cloud.securitycenter_v2.types.SecurityPosture): + The security posture associated with the + finding. + log_entries (MutableSequence[google.cloud.securitycenter_v2.types.LogEntry]): + Log entries that are relevant to the finding. + load_balancers (MutableSequence[google.cloud.securitycenter_v2.types.LoadBalancer]): + The load balancers associated with the + finding. + """ + + class State(proto.Enum): + r"""The state of the finding. + + Values: + STATE_UNSPECIFIED (0): + Unspecified state. + ACTIVE (1): + The finding requires attention and has not + been addressed yet. + INACTIVE (2): + The finding has been fixed, triaged as a + non-issue or otherwise addressed and is no + longer active. + """ + STATE_UNSPECIFIED = 0 + ACTIVE = 1 + INACTIVE = 2 + + class Severity(proto.Enum): + r"""The severity of the finding. + + Values: + SEVERITY_UNSPECIFIED (0): + This value is used for findings when a source + doesn't write a severity value. + CRITICAL (1): + Vulnerability: + + A critical vulnerability is easily discoverable + by an external actor, exploitable, and results + in the direct ability to execute arbitrary code, + exfiltrate data, and otherwise gain additional + access and privileges to cloud resources and + workloads. Examples include publicly accessible + unprotected user data and public SSH access with + weak or no passwords. + + Threat: + + Indicates a threat that is able to access, + modify, or delete data or execute unauthorized + code within existing resources. + HIGH (2): + Vulnerability: + + A high risk vulnerability can be easily + discovered and exploited in combination with + other vulnerabilities in order to gain direct + access and the ability to execute arbitrary + code, exfiltrate data, and otherwise gain + additional access and privileges to cloud + resources and workloads. An example is a + database with weak or no passwords that is only + accessible internally. This database could + easily be compromised by an actor that had + access to the internal network. + + Threat: + + Indicates a threat that is able to create new + computational resources in an environment but + not able to access data or execute code in + existing resources. + MEDIUM (3): + Vulnerability: + + A medium risk vulnerability could be used by an + actor to gain access to resources or privileges + that enable them to eventually (through multiple + steps or a complex exploit) gain access and the + ability to execute arbitrary code or exfiltrate + data. An example is a service account with + access to more projects than it should have. If + an actor gains access to the service account, + they could potentially use that access to + manipulate a project the service account was not + intended to. + + Threat: + + Indicates a threat that is able to cause + operational impact but may not access data or + execute unauthorized code. + LOW (4): + Vulnerability: + + A low risk vulnerability hampers a security + organization's ability to detect vulnerabilities + or active threats in their deployment, or + prevents the root cause investigation of + security issues. An example is monitoring and + logs being disabled for resource configurations + and access. + + Threat: + + Indicates a threat that has obtained minimal + access to an environment but is not able to + access data, execute code, or create resources. + """ + SEVERITY_UNSPECIFIED = 0 + CRITICAL = 1 + HIGH = 2 + MEDIUM = 3 + LOW = 4 + + class Mute(proto.Enum): + r"""Mute state a finding can be in. + + Values: + MUTE_UNSPECIFIED (0): + Unspecified. + MUTED (1): + Finding has been muted. + UNMUTED (2): + Finding has been unmuted. + UNDEFINED (3): + Finding has never been muted/unmuted. + """ + MUTE_UNSPECIFIED = 0 + MUTED = 1 + UNMUTED = 2 + UNDEFINED = 3 + + class FindingClass(proto.Enum): + r"""Represents what kind of Finding it is. + + Values: + FINDING_CLASS_UNSPECIFIED (0): + Unspecified finding class. + THREAT (1): + Describes unwanted or malicious activity. + VULNERABILITY (2): + Describes a potential weakness in software + that increases risk to Confidentiality & + Integrity & Availability. + MISCONFIGURATION (3): + Describes a potential weakness in cloud + resource/asset configuration that increases + risk. + OBSERVATION (4): + Describes a security observation that is for + informational purposes. + SCC_ERROR (5): + Describes an error that prevents some SCC + functionality. + POSTURE_VIOLATION (6): + Describes a potential security risk due to a + change in the security posture. + """ + FINDING_CLASS_UNSPECIFIED = 0 + THREAT = 1 + VULNERABILITY = 2 + MISCONFIGURATION = 3 + OBSERVATION = 4 + SCC_ERROR = 5 + POSTURE_VIOLATION = 6 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + canonical_name: str = proto.Field( + proto.STRING, + number=2, + ) + parent: str = proto.Field( + proto.STRING, + number=3, + ) + resource_name: str = proto.Field( + proto.STRING, + number=4, + ) + state: State = proto.Field( + proto.ENUM, + number=6, + enum=State, + ) + category: str = proto.Field( + proto.STRING, + number=7, + ) + external_uri: str = proto.Field( + proto.STRING, + number=8, + ) + source_properties: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=9, + message=struct_pb2.Value, + ) + security_marks: gcs_security_marks.SecurityMarks = proto.Field( + proto.MESSAGE, + number=10, + message=gcs_security_marks.SecurityMarks, + ) + event_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=11, + message=timestamp_pb2.Timestamp, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + severity: Severity = proto.Field( + proto.ENUM, + number=14, + enum=Severity, + ) + mute: Mute = proto.Field( + proto.ENUM, + number=15, + enum=Mute, + ) + finding_class: FindingClass = proto.Field( + proto.ENUM, + number=16, + enum=FindingClass, + ) + indicator: gcs_indicator.Indicator = proto.Field( + proto.MESSAGE, + number=17, + message=gcs_indicator.Indicator, + ) + vulnerability: gcs_vulnerability.Vulnerability = proto.Field( + proto.MESSAGE, + number=18, + message=gcs_vulnerability.Vulnerability, + ) + mute_update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=19, + message=timestamp_pb2.Timestamp, + ) + external_systems: MutableMapping[ + str, external_system.ExternalSystem + ] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=20, + message=external_system.ExternalSystem, + ) + mitre_attack: gcs_mitre_attack.MitreAttack = proto.Field( + proto.MESSAGE, + number=21, + message=gcs_mitre_attack.MitreAttack, + ) + access: gcs_access.Access = proto.Field( + proto.MESSAGE, + number=22, + message=gcs_access.Access, + ) + connections: MutableSequence[connection.Connection] = proto.RepeatedField( + proto.MESSAGE, + number=23, + message=connection.Connection, + ) + mute_initiator: str = proto.Field( + proto.STRING, + number=24, + ) + processes: MutableSequence[process.Process] = proto.RepeatedField( + proto.MESSAGE, + number=25, + message=process.Process, + ) + contacts: MutableMapping[str, contact_details.ContactDetails] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=26, + message=contact_details.ContactDetails, + ) + compliances: MutableSequence[compliance.Compliance] = proto.RepeatedField( + proto.MESSAGE, + number=27, + message=compliance.Compliance, + ) + parent_display_name: str = proto.Field( + proto.STRING, + number=29, + ) + description: str = proto.Field( + proto.STRING, + number=30, + ) + exfiltration: gcs_exfiltration.Exfiltration = proto.Field( + proto.MESSAGE, + number=31, + message=gcs_exfiltration.Exfiltration, + ) + iam_bindings: MutableSequence[iam_binding.IamBinding] = proto.RepeatedField( + proto.MESSAGE, + number=32, + message=iam_binding.IamBinding, + ) + next_steps: str = proto.Field( + proto.STRING, + number=33, + ) + module_name: str = proto.Field( + proto.STRING, + number=34, + ) + containers: MutableSequence[container.Container] = proto.RepeatedField( + proto.MESSAGE, + number=35, + message=container.Container, + ) + kubernetes: gcs_kubernetes.Kubernetes = proto.Field( + proto.MESSAGE, + number=36, + message=gcs_kubernetes.Kubernetes, + ) + database: gcs_database.Database = proto.Field( + proto.MESSAGE, + number=37, + message=gcs_database.Database, + ) + attack_exposure: gcs_attack_exposure.AttackExposure = proto.Field( + proto.MESSAGE, + number=38, + message=gcs_attack_exposure.AttackExposure, + ) + files: MutableSequence[file.File] = proto.RepeatedField( + proto.MESSAGE, + number=39, + message=file.File, + ) + cloud_dlp_inspection: gcs_cloud_dlp_inspection.CloudDlpInspection = proto.Field( + proto.MESSAGE, + number=40, + message=gcs_cloud_dlp_inspection.CloudDlpInspection, + ) + cloud_dlp_data_profile: gcs_cloud_dlp_data_profile.CloudDlpDataProfile = ( + proto.Field( + proto.MESSAGE, + number=41, + message=gcs_cloud_dlp_data_profile.CloudDlpDataProfile, + ) + ) + kernel_rootkit: gcs_kernel_rootkit.KernelRootkit = proto.Field( + proto.MESSAGE, + number=42, + message=gcs_kernel_rootkit.KernelRootkit, + ) + org_policies: MutableSequence[org_policy.OrgPolicy] = proto.RepeatedField( + proto.MESSAGE, + number=43, + message=org_policy.OrgPolicy, + ) + application: gcs_application.Application = proto.Field( + proto.MESSAGE, + number=45, + message=gcs_application.Application, + ) + backup_disaster_recovery: gcs_backup_disaster_recovery.BackupDisasterRecovery = ( + proto.Field( + proto.MESSAGE, + number=47, + message=gcs_backup_disaster_recovery.BackupDisasterRecovery, + ) + ) + security_posture: gcs_security_posture.SecurityPosture = proto.Field( + proto.MESSAGE, + number=48, + message=gcs_security_posture.SecurityPosture, + ) + log_entries: MutableSequence[log_entry.LogEntry] = proto.RepeatedField( + proto.MESSAGE, + number=49, + message=log_entry.LogEntry, + ) + load_balancers: MutableSequence[load_balancer.LoadBalancer] = proto.RepeatedField( + proto.MESSAGE, + number=50, + message=load_balancer.LoadBalancer, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/iam_binding.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/iam_binding.py new file mode 100644 index 000000000000..ce9eaaef14b6 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/iam_binding.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "IamBinding", + }, +) + + +class IamBinding(proto.Message): + r"""Represents a particular IAM binding, which captures a + member's role addition, removal, or state. + + Attributes: + action (google.cloud.securitycenter_v2.types.IamBinding.Action): + The action that was performed on a Binding. + role (str): + Role that is assigned to "members". + For example, "roles/viewer", "roles/editor", or + "roles/owner". + member (str): + A single identity requesting access for a + Cloud Platform resource, for example, + "foo@google.com". + """ + + class Action(proto.Enum): + r"""The type of action performed on a Binding in a policy. + + Values: + ACTION_UNSPECIFIED (0): + Unspecified. + ADD (1): + Addition of a Binding. + REMOVE (2): + Removal of a Binding. + """ + ACTION_UNSPECIFIED = 0 + ADD = 1 + REMOVE = 2 + + action: Action = proto.Field( + proto.ENUM, + number=1, + enum=Action, + ) + role: str = proto.Field( + proto.STRING, + number=2, + ) + member: str = proto.Field( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/indicator.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/indicator.py new file mode 100644 index 000000000000..1076b985c5e5 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/indicator.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Indicator", + }, +) + + +class Indicator(proto.Message): + r"""Represents what's commonly known as an *indicator of compromise* + (IoC) in computer forensics. This is an artifact observed on a + network or in an operating system that, with high confidence, + indicates a computer intrusion. For more information, see `Indicator + of + compromise `__. + + Attributes: + ip_addresses (MutableSequence[str]): + The list of IP addresses that are associated + with the finding. + domains (MutableSequence[str]): + List of domains associated to the Finding. + signatures (MutableSequence[google.cloud.securitycenter_v2.types.Indicator.ProcessSignature]): + The list of matched signatures indicating + that the given process is present in the + environment. + uris (MutableSequence[str]): + The list of URIs associated to the Findings. + """ + + class ProcessSignature(proto.Message): + r"""Indicates what signature matched this process. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + memory_hash_signature (google.cloud.securitycenter_v2.types.Indicator.ProcessSignature.MemoryHashSignature): + Signature indicating that a binary family was + matched. + + This field is a member of `oneof`_ ``signature``. + yara_rule_signature (google.cloud.securitycenter_v2.types.Indicator.ProcessSignature.YaraRuleSignature): + Signature indicating that a YARA rule was + matched. + + This field is a member of `oneof`_ ``signature``. + signature_type (google.cloud.securitycenter_v2.types.Indicator.ProcessSignature.SignatureType): + Describes the type of resource associated + with the signature. + """ + + class SignatureType(proto.Enum): + r"""Possible resource types to be associated with a signature. + + Values: + SIGNATURE_TYPE_UNSPECIFIED (0): + The default signature type. + SIGNATURE_TYPE_PROCESS (1): + Used for signatures concerning processes. + SIGNATURE_TYPE_FILE (2): + Used for signatures concerning disks. + """ + SIGNATURE_TYPE_UNSPECIFIED = 0 + SIGNATURE_TYPE_PROCESS = 1 + SIGNATURE_TYPE_FILE = 2 + + class MemoryHashSignature(proto.Message): + r"""A signature corresponding to memory page hashes. + + Attributes: + binary_family (str): + The binary family. + detections (MutableSequence[google.cloud.securitycenter_v2.types.Indicator.ProcessSignature.MemoryHashSignature.Detection]): + The list of memory hash detections + contributing to the binary family match. + """ + + class Detection(proto.Message): + r"""Memory hash detection contributing to the binary family + match. + + Attributes: + binary (str): + The name of the binary associated with the + memory hash signature detection. + percent_pages_matched (float): + The percentage of memory page hashes in the + signature that were matched. + """ + + binary: str = proto.Field( + proto.STRING, + number=2, + ) + percent_pages_matched: float = proto.Field( + proto.DOUBLE, + number=3, + ) + + binary_family: str = proto.Field( + proto.STRING, + number=1, + ) + detections: MutableSequence[ + "Indicator.ProcessSignature.MemoryHashSignature.Detection" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="Indicator.ProcessSignature.MemoryHashSignature.Detection", + ) + + class YaraRuleSignature(proto.Message): + r"""A signature corresponding to a YARA rule. + + Attributes: + yara_rule (str): + The name of the YARA rule. + """ + + yara_rule: str = proto.Field( + proto.STRING, + number=5, + ) + + memory_hash_signature: "Indicator.ProcessSignature.MemoryHashSignature" = ( + proto.Field( + proto.MESSAGE, + number=6, + oneof="signature", + message="Indicator.ProcessSignature.MemoryHashSignature", + ) + ) + yara_rule_signature: "Indicator.ProcessSignature.YaraRuleSignature" = ( + proto.Field( + proto.MESSAGE, + number=7, + oneof="signature", + message="Indicator.ProcessSignature.YaraRuleSignature", + ) + ) + signature_type: "Indicator.ProcessSignature.SignatureType" = proto.Field( + proto.ENUM, + number=8, + enum="Indicator.ProcessSignature.SignatureType", + ) + + ip_addresses: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + domains: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + signatures: MutableSequence[ProcessSignature] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=ProcessSignature, + ) + uris: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/kernel_rootkit.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/kernel_rootkit.py new file mode 100644 index 000000000000..edc5dd14fb7a --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/kernel_rootkit.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "KernelRootkit", + }, +) + + +class KernelRootkit(proto.Message): + r"""Kernel mode rootkit signatures. + + Attributes: + name (str): + Rootkit name, when available. + unexpected_code_modification (bool): + True if unexpected modifications of kernel + code memory are present. + unexpected_read_only_data_modification (bool): + True if unexpected modifications of kernel + read-only data memory are present. + unexpected_ftrace_handler (bool): + True if ``ftrace`` points are present with callbacks + pointing to regions that are not in the expected kernel or + module code range. + unexpected_kprobe_handler (bool): + True if ``kprobe`` points are present with callbacks + pointing to regions that are not in the expected kernel or + module code range. + unexpected_kernel_code_pages (bool): + True if kernel code pages that are not in the + expected kernel or module code regions are + present. + unexpected_system_call_handler (bool): + True if system call handlers that are are not + in the expected kernel or module code regions + are present. + unexpected_interrupt_handler (bool): + True if interrupt handlers that are are not + in the expected kernel or module code regions + are present. + unexpected_processes_in_runqueue (bool): + True if unexpected processes in the scheduler + run queue are present. Such processes are in the + run queue, but not in the process task list. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + unexpected_code_modification: bool = proto.Field( + proto.BOOL, + number=2, + ) + unexpected_read_only_data_modification: bool = proto.Field( + proto.BOOL, + number=3, + ) + unexpected_ftrace_handler: bool = proto.Field( + proto.BOOL, + number=4, + ) + unexpected_kprobe_handler: bool = proto.Field( + proto.BOOL, + number=5, + ) + unexpected_kernel_code_pages: bool = proto.Field( + proto.BOOL, + number=6, + ) + unexpected_system_call_handler: bool = proto.Field( + proto.BOOL, + number=7, + ) + unexpected_interrupt_handler: bool = proto.Field( + proto.BOOL, + number=8, + ) + unexpected_processes_in_runqueue: bool = proto.Field( + proto.BOOL, + number=9, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/kubernetes.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/kubernetes.py new file mode 100644 index 000000000000..1f47a938f512 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/kubernetes.py @@ -0,0 +1,398 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.securitycenter_v2.types import container, label + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Kubernetes", + }, +) + + +class Kubernetes(proto.Message): + r"""Kubernetes-related attributes. + + Attributes: + pods (MutableSequence[google.cloud.securitycenter_v2.types.Kubernetes.Pod]): + Kubernetes + `Pods `__ + associated with the finding. This field contains Pod records + for each container that is owned by a Pod. + nodes (MutableSequence[google.cloud.securitycenter_v2.types.Kubernetes.Node]): + Provides Kubernetes + `node `__ + information. + node_pools (MutableSequence[google.cloud.securitycenter_v2.types.Kubernetes.NodePool]): + GKE `node + pools `__ + associated with the finding. This field contains node pool + information for each node, when it is available. + roles (MutableSequence[google.cloud.securitycenter_v2.types.Kubernetes.Role]): + Provides Kubernetes role information for findings that + involve `Roles or + ClusterRoles `__. + bindings (MutableSequence[google.cloud.securitycenter_v2.types.Kubernetes.Binding]): + Provides Kubernetes role binding information for findings + that involve `RoleBindings or + ClusterRoleBindings `__. + access_reviews (MutableSequence[google.cloud.securitycenter_v2.types.Kubernetes.AccessReview]): + Provides information on any Kubernetes access + reviews (privilege checks) relevant to the + finding. + objects (MutableSequence[google.cloud.securitycenter_v2.types.Kubernetes.Object]): + Kubernetes objects related to the finding. + """ + + class Pod(proto.Message): + r"""A Kubernetes Pod. + + Attributes: + ns (str): + Kubernetes Pod namespace. + name (str): + Kubernetes Pod name. + labels (MutableSequence[google.cloud.securitycenter_v2.types.Label]): + Pod labels. For Kubernetes containers, these + are applied to the container. + containers (MutableSequence[google.cloud.securitycenter_v2.types.Container]): + Pod containers associated with this finding, + if any. + """ + + ns: str = proto.Field( + proto.STRING, + number=1, + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + labels: MutableSequence[label.Label] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=label.Label, + ) + containers: MutableSequence[container.Container] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=container.Container, + ) + + class Node(proto.Message): + r"""Kubernetes nodes associated with the finding. + + Attributes: + name (str): + `Full resource + name `__ of + the Compute Engine VM running the cluster node. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + class NodePool(proto.Message): + r"""Provides GKE node pool information. + + Attributes: + name (str): + Kubernetes node pool name. + nodes (MutableSequence[google.cloud.securitycenter_v2.types.Kubernetes.Node]): + Nodes associated with the finding. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + nodes: MutableSequence["Kubernetes.Node"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="Kubernetes.Node", + ) + + class Role(proto.Message): + r"""Kubernetes Role or ClusterRole. + + Attributes: + kind (google.cloud.securitycenter_v2.types.Kubernetes.Role.Kind): + Role type. + ns (str): + Role namespace. + name (str): + Role name. + """ + + class Kind(proto.Enum): + r"""Types of Kubernetes roles. + + Values: + KIND_UNSPECIFIED (0): + Role type is not specified. + ROLE (1): + Kubernetes Role. + CLUSTER_ROLE (2): + Kubernetes ClusterRole. + """ + KIND_UNSPECIFIED = 0 + ROLE = 1 + CLUSTER_ROLE = 2 + + kind: "Kubernetes.Role.Kind" = proto.Field( + proto.ENUM, + number=1, + enum="Kubernetes.Role.Kind", + ) + ns: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + + class Binding(proto.Message): + r"""Represents a Kubernetes RoleBinding or ClusterRoleBinding. + + Attributes: + ns (str): + Namespace for the binding. + name (str): + Name for the binding. + role (google.cloud.securitycenter_v2.types.Kubernetes.Role): + The Role or ClusterRole referenced by the + binding. + subjects (MutableSequence[google.cloud.securitycenter_v2.types.Kubernetes.Subject]): + Represents one or more subjects that are + bound to the role. Not always available for + PATCH requests. + """ + + ns: str = proto.Field( + proto.STRING, + number=1, + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + role: "Kubernetes.Role" = proto.Field( + proto.MESSAGE, + number=3, + message="Kubernetes.Role", + ) + subjects: MutableSequence["Kubernetes.Subject"] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="Kubernetes.Subject", + ) + + class Subject(proto.Message): + r"""Represents a Kubernetes subject. + + Attributes: + kind (google.cloud.securitycenter_v2.types.Kubernetes.Subject.AuthType): + Authentication type for the subject. + ns (str): + Namespace for the subject. + name (str): + Name for the subject. + """ + + class AuthType(proto.Enum): + r"""Auth types that can be used for the subject's kind field. + + Values: + AUTH_TYPE_UNSPECIFIED (0): + Authentication is not specified. + USER (1): + User with valid certificate. + SERVICEACCOUNT (2): + Users managed by Kubernetes API with + credentials stored as secrets. + GROUP (3): + Collection of users. + """ + AUTH_TYPE_UNSPECIFIED = 0 + USER = 1 + SERVICEACCOUNT = 2 + GROUP = 3 + + kind: "Kubernetes.Subject.AuthType" = proto.Field( + proto.ENUM, + number=1, + enum="Kubernetes.Subject.AuthType", + ) + ns: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + + class AccessReview(proto.Message): + r"""Conveys information about a Kubernetes access review (such as one + returned by a + ```kubectl auth can-i`` `__ + command) that was involved in a finding. + + Attributes: + group (str): + The API group of the resource. "*" means all. + ns (str): + Namespace of the action being requested. + Currently, there is no distinction between no + namespace and all namespaces. Both are + represented by "" (empty). + name (str): + The name of the resource being requested. + Empty means all. + resource (str): + The optional resource type requested. "*" means all. + subresource (str): + The optional subresource type. + verb (str): + A Kubernetes resource API verb, like get, list, watch, + create, update, delete, proxy. "*" means all. + version (str): + The API version of the resource. "*" means all. + """ + + group: str = proto.Field( + proto.STRING, + number=1, + ) + ns: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + resource: str = proto.Field( + proto.STRING, + number=4, + ) + subresource: str = proto.Field( + proto.STRING, + number=5, + ) + verb: str = proto.Field( + proto.STRING, + number=6, + ) + version: str = proto.Field( + proto.STRING, + number=7, + ) + + class Object(proto.Message): + r"""Kubernetes object related to the finding, uniquely identified + by GKNN. Used if the object Kind is not one of Pod, Node, + NodePool, Binding, or AccessReview. + + Attributes: + group (str): + Kubernetes object group, such as + "policy.k8s.io/v1". + kind (str): + Kubernetes object kind, such as "Namespace". + ns (str): + Kubernetes object namespace. Must be a valid + DNS label. Named "ns" to avoid collision with + C++ namespace keyword. For details see + https://kubernetes.io/docs/tasks/administer-cluster/namespaces/. + name (str): + Kubernetes object name. For details see + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/. + containers (MutableSequence[google.cloud.securitycenter_v2.types.Container]): + Pod containers associated with this finding, + if any. + """ + + group: str = proto.Field( + proto.STRING, + number=1, + ) + kind: str = proto.Field( + proto.STRING, + number=2, + ) + ns: str = proto.Field( + proto.STRING, + number=3, + ) + name: str = proto.Field( + proto.STRING, + number=4, + ) + containers: MutableSequence[container.Container] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=container.Container, + ) + + pods: MutableSequence[Pod] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=Pod, + ) + nodes: MutableSequence[Node] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=Node, + ) + node_pools: MutableSequence[NodePool] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=NodePool, + ) + roles: MutableSequence[Role] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=Role, + ) + bindings: MutableSequence[Binding] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=Binding, + ) + access_reviews: MutableSequence[AccessReview] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=AccessReview, + ) + objects: MutableSequence[Object] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message=Object, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/label.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/label.py new file mode 100644 index 000000000000..5ccb9072d756 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/label.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Label", + }, +) + + +class Label(proto.Message): + r"""Represents a generic name-value label. A label has separate name and + value fields to support filtering with the ``contains()`` function. + For more information, see `Filtering on array-type + fields `__. + + Attributes: + name (str): + Name of the label. + value (str): + Value that corresponds to the label's name. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/load_balancer.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/load_balancer.py new file mode 100644 index 000000000000..687c8a09fdc2 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/load_balancer.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "LoadBalancer", + }, +) + + +class LoadBalancer(proto.Message): + r"""Contains information related to the load balancer associated + with the finding. + + Attributes: + name (str): + The name of the load balancer associated with + the finding. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/log_entry.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/log_entry.py new file mode 100644 index 000000000000..df29ce9bfbe4 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/log_entry.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "LogEntry", + "CloudLoggingEntry", + }, +) + + +class LogEntry(proto.Message): + r"""An individual entry in a log. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + cloud_logging_entry (google.cloud.securitycenter_v2.types.CloudLoggingEntry): + An individual entry in a log stored in Cloud + Logging. + + This field is a member of `oneof`_ ``log_entry``. + """ + + cloud_logging_entry: "CloudLoggingEntry" = proto.Field( + proto.MESSAGE, + number=1, + oneof="log_entry", + message="CloudLoggingEntry", + ) + + +class CloudLoggingEntry(proto.Message): + r"""Metadata taken from a `Cloud Logging + LogEntry `__ + + Attributes: + insert_id (str): + A unique identifier for the log entry. + log_id (str): + The type of the log (part of ``log_name``. ``log_name`` is + the resource name of the log to which this log entry + belongs). For example: + ``cloudresourcemanager.googleapis.com/activity`` Note that + this field is not URL-encoded, unlike in ``LogEntry``. + resource_container (str): + The organization, folder, or project of the + monitored resource that produced this log entry. + timestamp (google.protobuf.timestamp_pb2.Timestamp): + The time the event described by the log entry + occurred. + """ + + insert_id: str = proto.Field( + proto.STRING, + number=1, + ) + log_id: str = proto.Field( + proto.STRING, + number=2, + ) + resource_container: str = proto.Field( + proto.STRING, + number=3, + ) + timestamp: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/mitre_attack.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/mitre_attack.py new file mode 100644 index 000000000000..ef706800ae64 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/mitre_attack.py @@ -0,0 +1,322 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "MitreAttack", + }, +) + + +class MitreAttack(proto.Message): + r"""MITRE ATT&CK tactics and techniques related to this finding. + See: https://attack.mitre.org + + Attributes: + primary_tactic (google.cloud.securitycenter_v2.types.MitreAttack.Tactic): + The MITRE ATT&CK tactic most closely + represented by this finding, if any. + primary_techniques (MutableSequence[google.cloud.securitycenter_v2.types.MitreAttack.Technique]): + The MITRE ATT&CK technique most closely represented by this + finding, if any. primary_techniques is a repeated field + because there are multiple levels of MITRE ATT&CK + techniques. If the technique most closely represented by + this finding is a sub-technique (e.g. + ``SCANNING_IP_BLOCKS``), both the sub-technique and its + parent technique(s) will be listed (e.g. + ``SCANNING_IP_BLOCKS``, ``ACTIVE_SCANNING``). + additional_tactics (MutableSequence[google.cloud.securitycenter_v2.types.MitreAttack.Tactic]): + Additional MITRE ATT&CK tactics related to + this finding, if any. + additional_techniques (MutableSequence[google.cloud.securitycenter_v2.types.MitreAttack.Technique]): + Additional MITRE ATT&CK techniques related to + this finding, if any, along with any of their + respective parent techniques. + version (str): + The MITRE ATT&CK version referenced by the + above fields. E.g. "8". + """ + + class Tactic(proto.Enum): + r"""MITRE ATT&CK tactics that can be referenced by SCC findings. + See: https://attack.mitre.org/tactics/enterprise/ + + Values: + TACTIC_UNSPECIFIED (0): + Unspecified value. + RECONNAISSANCE (1): + TA0043 + RESOURCE_DEVELOPMENT (2): + TA0042 + INITIAL_ACCESS (5): + TA0001 + EXECUTION (3): + TA0002 + PERSISTENCE (6): + TA0003 + PRIVILEGE_ESCALATION (8): + TA0004 + DEFENSE_EVASION (7): + TA0005 + CREDENTIAL_ACCESS (9): + TA0006 + DISCOVERY (10): + TA0007 + LATERAL_MOVEMENT (11): + TA0008 + COLLECTION (12): + TA0009 + COMMAND_AND_CONTROL (4): + TA0011 + EXFILTRATION (13): + TA0010 + IMPACT (14): + TA0040 + """ + TACTIC_UNSPECIFIED = 0 + RECONNAISSANCE = 1 + RESOURCE_DEVELOPMENT = 2 + INITIAL_ACCESS = 5 + EXECUTION = 3 + PERSISTENCE = 6 + PRIVILEGE_ESCALATION = 8 + DEFENSE_EVASION = 7 + CREDENTIAL_ACCESS = 9 + DISCOVERY = 10 + LATERAL_MOVEMENT = 11 + COLLECTION = 12 + COMMAND_AND_CONTROL = 4 + EXFILTRATION = 13 + IMPACT = 14 + + class Technique(proto.Enum): + r"""MITRE ATT&CK techniques that can be referenced by SCC + findings. See: https://attack.mitre.org/techniques/enterprise/ + Next ID: 59 + + Values: + TECHNIQUE_UNSPECIFIED (0): + Unspecified value. + MASQUERADING (49): + T1036 + MATCH_LEGITIMATE_NAME_OR_LOCATION (50): + T1036.005 + BOOT_OR_LOGON_INITIALIZATION_SCRIPTS (37): + T1037 + STARTUP_ITEMS (38): + T1037.005 + NETWORK_SERVICE_DISCOVERY (32): + T1046 + PROCESS_DISCOVERY (56): + T1057 + COMMAND_AND_SCRIPTING_INTERPRETER (6): + T1059 + UNIX_SHELL (7): + T1059.004 + PERMISSION_GROUPS_DISCOVERY (18): + T1069 + CLOUD_GROUPS (19): + T1069.003 + APPLICATION_LAYER_PROTOCOL (45): + T1071 + DNS (46): + T1071.004 + SOFTWARE_DEPLOYMENT_TOOLS (47): + T1072 + VALID_ACCOUNTS (14): + T1078 + DEFAULT_ACCOUNTS (35): + T1078.001 + LOCAL_ACCOUNTS (15): + T1078.003 + CLOUD_ACCOUNTS (16): + T1078.004 + PROXY (9): + T1090 + EXTERNAL_PROXY (10): + T1090.002 + MULTI_HOP_PROXY (11): + T1090.003 + ACCOUNT_MANIPULATION (22): + T1098 + ADDITIONAL_CLOUD_CREDENTIALS (40): + T1098.001 + SSH_AUTHORIZED_KEYS (23): + T1098.004 + ADDITIONAL_CONTAINER_CLUSTER_ROLES (58): + T1098.006 + INGRESS_TOOL_TRANSFER (3): + T1105 + NATIVE_API (4): + T1106 + BRUTE_FORCE (44): + T1110 + SHARED_MODULES (5): + T1129 + ACCESS_TOKEN_MANIPULATION (33): + T1134 + TOKEN_IMPERSONATION_OR_THEFT (39): + T1134.001 + EXPLOIT_PUBLIC_FACING_APPLICATION (27): + T1190 + DOMAIN_POLICY_MODIFICATION (30): + T1484 + DATA_DESTRUCTION (29): + T1485 + SERVICE_STOP (52): + T1489 + INHIBIT_SYSTEM_RECOVERY (36): + T1490 + RESOURCE_HIJACKING (8): + T1496 + NETWORK_DENIAL_OF_SERVICE (17): + T1498 + CLOUD_SERVICE_DISCOVERY (48): + T1526 + STEAL_APPLICATION_ACCESS_TOKEN (42): + T1528 + ACCOUNT_ACCESS_REMOVAL (51): + T1531 + STEAL_WEB_SESSION_COOKIE (25): + T1539 + CREATE_OR_MODIFY_SYSTEM_PROCESS (24): + T1543 + ABUSE_ELEVATION_CONTROL_MECHANISM (34): + T1548 + UNSECURED_CREDENTIALS (13): + T1552 + MODIFY_AUTHENTICATION_PROCESS (28): + T1556 + IMPAIR_DEFENSES (31): + T1562 + DISABLE_OR_MODIFY_TOOLS (55): + T1562.001 + EXFILTRATION_OVER_WEB_SERVICE (20): + T1567 + EXFILTRATION_TO_CLOUD_STORAGE (21): + T1567.002 + DYNAMIC_RESOLUTION (12): + T1568 + LATERAL_TOOL_TRANSFER (41): + T1570 + MODIFY_CLOUD_COMPUTE_INFRASTRUCTURE (26): + T1578 + CREATE_SNAPSHOT (54): + T1578.001 + CLOUD_INFRASTRUCTURE_DISCOVERY (53): + T1580 + OBTAIN_CAPABILITIES (43): + T1588 + ACTIVE_SCANNING (1): + T1595 + SCANNING_IP_BLOCKS (2): + T1595.001 + CONTAINER_AND_RESOURCE_DISCOVERY (57): + T1613 + """ + TECHNIQUE_UNSPECIFIED = 0 + MASQUERADING = 49 + MATCH_LEGITIMATE_NAME_OR_LOCATION = 50 + BOOT_OR_LOGON_INITIALIZATION_SCRIPTS = 37 + STARTUP_ITEMS = 38 + NETWORK_SERVICE_DISCOVERY = 32 + PROCESS_DISCOVERY = 56 + COMMAND_AND_SCRIPTING_INTERPRETER = 6 + UNIX_SHELL = 7 + PERMISSION_GROUPS_DISCOVERY = 18 + CLOUD_GROUPS = 19 + APPLICATION_LAYER_PROTOCOL = 45 + DNS = 46 + SOFTWARE_DEPLOYMENT_TOOLS = 47 + VALID_ACCOUNTS = 14 + DEFAULT_ACCOUNTS = 35 + LOCAL_ACCOUNTS = 15 + CLOUD_ACCOUNTS = 16 + PROXY = 9 + EXTERNAL_PROXY = 10 + MULTI_HOP_PROXY = 11 + ACCOUNT_MANIPULATION = 22 + ADDITIONAL_CLOUD_CREDENTIALS = 40 + SSH_AUTHORIZED_KEYS = 23 + ADDITIONAL_CONTAINER_CLUSTER_ROLES = 58 + INGRESS_TOOL_TRANSFER = 3 + NATIVE_API = 4 + BRUTE_FORCE = 44 + SHARED_MODULES = 5 + ACCESS_TOKEN_MANIPULATION = 33 + TOKEN_IMPERSONATION_OR_THEFT = 39 + EXPLOIT_PUBLIC_FACING_APPLICATION = 27 + DOMAIN_POLICY_MODIFICATION = 30 + DATA_DESTRUCTION = 29 + SERVICE_STOP = 52 + INHIBIT_SYSTEM_RECOVERY = 36 + RESOURCE_HIJACKING = 8 + NETWORK_DENIAL_OF_SERVICE = 17 + CLOUD_SERVICE_DISCOVERY = 48 + STEAL_APPLICATION_ACCESS_TOKEN = 42 + ACCOUNT_ACCESS_REMOVAL = 51 + STEAL_WEB_SESSION_COOKIE = 25 + CREATE_OR_MODIFY_SYSTEM_PROCESS = 24 + ABUSE_ELEVATION_CONTROL_MECHANISM = 34 + UNSECURED_CREDENTIALS = 13 + MODIFY_AUTHENTICATION_PROCESS = 28 + IMPAIR_DEFENSES = 31 + DISABLE_OR_MODIFY_TOOLS = 55 + EXFILTRATION_OVER_WEB_SERVICE = 20 + EXFILTRATION_TO_CLOUD_STORAGE = 21 + DYNAMIC_RESOLUTION = 12 + LATERAL_TOOL_TRANSFER = 41 + MODIFY_CLOUD_COMPUTE_INFRASTRUCTURE = 26 + CREATE_SNAPSHOT = 54 + CLOUD_INFRASTRUCTURE_DISCOVERY = 53 + OBTAIN_CAPABILITIES = 43 + ACTIVE_SCANNING = 1 + SCANNING_IP_BLOCKS = 2 + CONTAINER_AND_RESOURCE_DISCOVERY = 57 + + primary_tactic: Tactic = proto.Field( + proto.ENUM, + number=1, + enum=Tactic, + ) + primary_techniques: MutableSequence[Technique] = proto.RepeatedField( + proto.ENUM, + number=2, + enum=Technique, + ) + additional_tactics: MutableSequence[Tactic] = proto.RepeatedField( + proto.ENUM, + number=3, + enum=Tactic, + ) + additional_techniques: MutableSequence[Technique] = proto.RepeatedField( + proto.ENUM, + number=4, + enum=Technique, + ) + version: str = proto.Field( + proto.STRING, + number=5, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/mute_config.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/mute_config.py new file mode 100644 index 000000000000..28df51d1d357 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/mute_config.py @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "MuteConfig", + }, +) + + +class MuteConfig(proto.Message): + r"""A mute config is a Cloud SCC resource that contains the + configuration to mute create/update events of findings. + + Attributes: + name (str): + This field will be ignored if provided on config creation. + The following list shows some examples of the format: + + - ``organizations/{organization}/muteConfigs/{mute_config}`` + - + + ``organizations/{organization}locations/{location}//muteConfigs/{mute_config}`` + + - ``folders/{folder}/muteConfigs/{mute_config}`` + - ``folders/{folder}/locations/{location}/muteConfigs/{mute_config}`` + - ``projects/{project}/muteConfigs/{mute_config}`` + - ``projects/{project}/locations/{location}/muteConfigs/{mute_config}`` + description (str): + A description of the mute config. + filter (str): + Required. An expression that defines the filter to apply + across create/update events of findings. While creating a + filter string, be mindful of the scope in which the mute + configuration is being created. E.g., If a filter contains + project = X but is created under the project = Y scope, it + might not match any findings. + + The following field and operator combinations are supported: + + - severity: ``=``, ``:`` + - category: ``=``, ``:`` + - resource.name: ``=``, ``:`` + - resource.project_name: ``=``, ``:`` + - resource.project_display_name: ``=``, ``:`` + - resource.folders.resource_folder: ``=``, ``:`` + - resource.parent_name: ``=``, ``:`` + - resource.parent_display_name: ``=``, ``:`` + - resource.type: ``=``, ``:`` + - finding_class: ``=``, ``:`` + - indicator.ip_addresses: ``=``, ``:`` + - indicator.domains: ``=``, ``:`` + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time at which the mute + config was created. This field is set by the + server and will be ignored if provided on config + creation. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The most recent time at which + the mute config was updated. This field is set + by the server and will be ignored if provided on + config creation or update. + most_recent_editor (str): + Output only. Email address of the user who + last edited the mute config. This field is set + by the server and will be ignored if provided on + config creation or update. + type_ (google.cloud.securitycenter_v2.types.MuteConfig.MuteConfigType): + Required. The type of the mute config, which + determines what type of mute state the config + affects. Immutable after creation. + """ + + class MuteConfigType(proto.Enum): + r"""The type of MuteConfig. + + Values: + MUTE_CONFIG_TYPE_UNSPECIFIED (0): + Unused. + STATIC (1): + A static mute config, which sets the static + mute state of future matching findings to muted. + Once the static mute state has been set, finding + or config modifications will not affect the + state. + """ + MUTE_CONFIG_TYPE_UNSPECIFIED = 0 + STATIC = 1 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + filter: str = proto.Field( + proto.STRING, + number=3, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + most_recent_editor: str = proto.Field( + proto.STRING, + number=6, + ) + type_: MuteConfigType = proto.Field( + proto.ENUM, + number=8, + enum=MuteConfigType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/notification_config.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/notification_config.py new file mode 100644 index 000000000000..e00250d588df --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/notification_config.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "NotificationConfig", + }, +) + + +class NotificationConfig(proto.Message): + r"""Cloud Security Command Center (Cloud SCC) notification + configs. + A notification config is a Cloud SCC resource that contains the + configuration to send notifications for create/update events of + findings, assets and etc. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + The relative resource name of this notification config. See: + https://cloud.google.com/apis/design/resource_names#relative_resource_name + The following list shows some examples: + + ``organizations/{organization_id}/locations/{location_id}/notificationConfigs/notify_public_bucket`` + + + ``folders/{folder_id}/locations/{location_id}/notificationConfigs/notify_public_bucket`` + + + ``projects/{project_id}/locations/{location_id}/notificationConfigs/notify_public_bucket`` + description (str): + The description of the notification config + (max of 1024 characters). + pubsub_topic (str): + The Pub/Sub topic to send notifications to. Its format is + "projects/[project_id]/topics/[topic]". + service_account (str): + Output only. The service account that needs + "pubsub.topics.publish" permission to publish to + the Pub/Sub topic. + streaming_config (google.cloud.securitycenter_v2.types.NotificationConfig.StreamingConfig): + The config for triggering streaming-based + notifications. + + This field is a member of `oneof`_ ``notify_config``. + """ + + class StreamingConfig(proto.Message): + r"""The config for streaming-based notifications, which send each + event as soon as it is detected. + + Attributes: + filter (str): + Expression that defines the filter to apply across + create/update events of assets or findings as specified by + the event type. The expression is a list of zero or more + restrictions combined via logical operators ``AND`` and + ``OR``. Parentheses are supported, and ``OR`` has higher + precedence than ``AND``. + + Restrictions have the form `` `` + and may have a ``-`` character in front of them to indicate + negation. The fields map to those defined in the + corresponding resource. + + The supported operators are: + + - ``=`` for all value types. + - ``>``, ``<``, ``>=``, ``<=`` for integer values. + - ``:``, meaning substring matching, for strings. + + The supported value types are: + + - string literals in quotes. + - integer literals without quotes. + - boolean literals ``true`` and ``false`` without quotes. + """ + + filter: str = proto.Field( + proto.STRING, + number=1, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + pubsub_topic: str = proto.Field( + proto.STRING, + number=3, + ) + service_account: str = proto.Field( + proto.STRING, + number=4, + ) + streaming_config: StreamingConfig = proto.Field( + proto.MESSAGE, + number=5, + oneof="notify_config", + message=StreamingConfig, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/notification_message.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/notification_message.py new file mode 100644 index 000000000000..1f389e1deddc --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/notification_message.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.securitycenter_v2.types import finding as gcs_finding +from google.cloud.securitycenter_v2.types import resource as gcs_resource + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "NotificationMessage", + }, +) + + +class NotificationMessage(proto.Message): + r"""Cloud SCC's Notification + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + notification_config_name (str): + Name of the notification config that + generated current notification. + finding (google.cloud.securitycenter_v2.types.Finding): + If it's a Finding based notification config, + this field will be populated. + + This field is a member of `oneof`_ ``event``. + resource (google.cloud.securitycenter_v2.types.Resource): + The Cloud resource tied to this + notification's Finding. + """ + + notification_config_name: str = proto.Field( + proto.STRING, + number=1, + ) + finding: gcs_finding.Finding = proto.Field( + proto.MESSAGE, + number=2, + oneof="event", + message=gcs_finding.Finding, + ) + resource: gcs_resource.Resource = proto.Field( + proto.MESSAGE, + number=3, + message=gcs_resource.Resource, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/org_policy.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/org_policy.py new file mode 100644 index 000000000000..44f04ce0f63e --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/org_policy.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "OrgPolicy", + }, +) + + +class OrgPolicy(proto.Message): + r"""Contains information about the org policies associated with + the finding. + + Attributes: + name (str): + The resource name of the org policy. Example: + "organizations/{organization_id}/policies/{constraint_name}". + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/process.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/process.py new file mode 100644 index 000000000000..4737d7c9ff06 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/process.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.securitycenter_v2.types import file + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Process", + "EnvironmentVariable", + }, +) + + +class Process(proto.Message): + r"""Represents an operating system process. + + Attributes: + name (str): + The process name, as displayed in utilities like ``top`` and + ``ps``. This name can be accessed through + ``/proc/[pid]/comm`` and changed with + ``prctl(PR_SET_NAME)``. + binary (google.cloud.securitycenter_v2.types.File): + File information for the process executable. + libraries (MutableSequence[google.cloud.securitycenter_v2.types.File]): + File information for libraries loaded by the + process. + script (google.cloud.securitycenter_v2.types.File): + When the process represents the invocation of a script, + ``binary`` provides information about the interpreter, while + ``script`` provides information about the script file + provided to the interpreter. + args (MutableSequence[str]): + Process arguments as JSON encoded strings. + arguments_truncated (bool): + True if ``args`` is incomplete. + env_variables (MutableSequence[google.cloud.securitycenter_v2.types.EnvironmentVariable]): + Process environment variables. + env_variables_truncated (bool): + True if ``env_variables`` is incomplete. + pid (int): + The process ID. + parent_pid (int): + The parent process ID. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + binary: file.File = proto.Field( + proto.MESSAGE, + number=2, + message=file.File, + ) + libraries: MutableSequence[file.File] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=file.File, + ) + script: file.File = proto.Field( + proto.MESSAGE, + number=4, + message=file.File, + ) + args: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + arguments_truncated: bool = proto.Field( + proto.BOOL, + number=6, + ) + env_variables: MutableSequence["EnvironmentVariable"] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message="EnvironmentVariable", + ) + env_variables_truncated: bool = proto.Field( + proto.BOOL, + number=8, + ) + pid: int = proto.Field( + proto.INT64, + number=9, + ) + parent_pid: int = proto.Field( + proto.INT64, + number=10, + ) + + +class EnvironmentVariable(proto.Message): + r"""A name-value pair representing an environment variable used + in an operating system process. + + Attributes: + name (str): + Environment variable name as a JSON encoded + string. + val (str): + Environment variable value as a JSON encoded + string. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + val: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/resource.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/resource.py new file mode 100644 index 000000000000..2c05d978100b --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/resource.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Resource", + }, +) + + +class Resource(proto.Message): + r"""Information related to the Google Cloud resource. + + Attributes: + name (str): + The full resource name of the resource. See: + https://cloud.google.com/apis/design/resource_names#full_resource_name + display_name (str): + The human readable name of the resource. + type_ (str): + The full resource type of the resource. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + type_: str = proto.Field( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/resource_value_config.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/resource_value_config.py new file mode 100644 index 000000000000..414ea9982f36 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/resource_value_config.py @@ -0,0 +1,178 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "ResourceValue", + "ResourceValueConfig", + }, +) + + +class ResourceValue(proto.Enum): + r"""Value enum to map to a resource + + Values: + RESOURCE_VALUE_UNSPECIFIED (0): + Unspecific value + HIGH (1): + High resource value + MEDIUM (2): + Medium resource value + LOW (3): + Low resource value + NONE (4): + No resource value, e.g. ignore these + resources + """ + RESOURCE_VALUE_UNSPECIFIED = 0 + HIGH = 1 + MEDIUM = 2 + LOW = 3 + NONE = 4 + + +class ResourceValueConfig(proto.Message): + r"""A resource value config (RVC) is a mapping configuration of + user's resources to resource values. Used in Attack path + simulations. + + Attributes: + name (str): + Name for the resource value config + resource_value (google.cloud.securitycenter_v2.types.ResourceValue): + Resource value level this expression + represents Only required when there is no SDP + mapping in the request + tag_values (MutableSequence[str]): + Required. Tag values combined with AND to check against. + Values in the form "tagValues/123" E.g. [ "tagValues/123", + "tagValues/456", "tagValues/789" ] + https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing + resource_type (str): + Apply resource_value only to resources that match + resource_type. resource_type will be checked with "AND" of + other resources. E.g. "storage.googleapis.com/Bucket" with + resource_value "HIGH" will apply "HIGH" value only to + "storage.googleapis.com/Bucket" resources. + scope (str): + Project or folder to scope this config to. + For example, "project/456" would apply this + config only to resources in "project/456" + scope will be checked with "AND" of other + resources. + resource_labels_selector (MutableMapping[str, str]): + List of resource labels to search for, evaluated with AND. + E.g. "resource_labels_selector": {"key": "value", "env": + "prod"} will match resources with labels "key": "value" AND + "env": "prod" + https://cloud.google.com/resource-manager/docs/creating-managing-labels + description (str): + Description of the resource value config. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp this resource value + config was created. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp this resource value + config was last updated. + sensitive_data_protection_mapping (google.cloud.securitycenter_v2.types.ResourceValueConfig.SensitiveDataProtectionMapping): + A mapping of the sensitivity on Sensitive Data Protection + finding to resource values. This mapping can only be used in + combination with a resource_type that is related to + BigQuery, e.g. "bigquery.googleapis.com/Dataset". + """ + + class SensitiveDataProtectionMapping(proto.Message): + r"""Resource value mapping for Sensitive Data Protection findings If any + of these mappings have a resource value that is not unspecified, the + resource_value field will be ignored when reading this + configuration. + + Attributes: + high_sensitivity_mapping (google.cloud.securitycenter_v2.types.ResourceValue): + Resource value mapping for high-sensitivity + Sensitive Data Protection findings + medium_sensitivity_mapping (google.cloud.securitycenter_v2.types.ResourceValue): + Resource value mapping for medium-sensitivity + Sensitive Data Protection findings + """ + + high_sensitivity_mapping: "ResourceValue" = proto.Field( + proto.ENUM, + number=1, + enum="ResourceValue", + ) + medium_sensitivity_mapping: "ResourceValue" = proto.Field( + proto.ENUM, + number=2, + enum="ResourceValue", + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + resource_value: "ResourceValue" = proto.Field( + proto.ENUM, + number=2, + enum="ResourceValue", + ) + tag_values: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + resource_type: str = proto.Field( + proto.STRING, + number=4, + ) + scope: str = proto.Field( + proto.STRING, + number=5, + ) + resource_labels_selector: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=6, + ) + description: str = proto.Field( + proto.STRING, + number=7, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=8, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=9, + message=timestamp_pb2.Timestamp, + ) + sensitive_data_protection_mapping: SensitiveDataProtectionMapping = proto.Field( + proto.MESSAGE, + number=11, + message=SensitiveDataProtectionMapping, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/security_marks.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/security_marks.py new file mode 100644 index 000000000000..38eeb11be6f3 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/security_marks.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "SecurityMarks", + }, +) + + +class SecurityMarks(proto.Message): + r"""User specified security marks that are attached to the parent + Security Command Center resource. Security marks are scoped + within a Security Command Center organization -- they can be + modified and viewed by all users who have proper permissions on + the organization. + + Attributes: + name (str): + The relative resource name of the SecurityMarks. See: + https://cloud.google.com/apis/design/resource_names#relative_resource_name + The following list shows some examples: + + - ``organizations/{organization_id}/assets/{asset_id}/securityMarks`` + - + + ``organizations/{organization_id}/sources/{source_id}/findings/{finding_id}/securityMarks`` + + + ``organizations/{organization_id}/sources/{source_id}/locations/{location}/findings/{finding_id}/securityMarks`` + marks (MutableMapping[str, str]): + Mutable user specified security marks belonging to the + parent resource. Constraints are as follows: + + - Keys and values are treated as case insensitive + - Keys must be between 1 - 256 characters (inclusive) + - Keys must be letters, numbers, underscores, or dashes + - Values have leading and trailing whitespace trimmed, + remaining characters must be between 1 - 4096 characters + (inclusive) + canonical_name (str): + The canonical name of the marks. The following list shows + some examples: + + - \`organizations/{organization_id}/assets/{asset_id}/securityMarks" + - + + ``organizations/{organization_id}/sources/{source_id}/findings/{finding_id}/securityMarks" +``\ organizations/{organization_id}/sources/{source_id}/locations/{location}/findings/{finding_id}/securityMarks" + + - \`folders/{folder_id}/assets/{asset_id}/securityMarks" + - + + ``folders/{folder_id}/sources/{source_id}/findings/{finding_id}/securityMarks" +``\ folders/{folder_id}/sources/{source_id}/locations/{location}/findings/{finding_id}/securityMarks" + + - \`projects/{project_number}/assets/{asset_id}/securityMarks" + - + + ``projects/{project_number}/sources/{source_id}/findings/{finding_id}/securityMarks" +``\ projects/{project_number}/sources/{source_id}/locations/{location}/findings/{finding_id}/securityMarks". + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + marks: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=2, + ) + canonical_name: str = proto.Field( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/security_posture.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/security_posture.py new file mode 100644 index 000000000000..4ee2430010ae --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/security_posture.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "SecurityPosture", + }, +) + + +class SecurityPosture(proto.Message): + r"""Represents a posture that is deployed on Google Cloud by the + Security Command Center Posture Management service. A posture + contains one or more policy sets. A policy set is a group of + policies that enforce a set of security rules on Google Cloud. + + Attributes: + name (str): + Name of the posture, for example, ``CIS-Posture``. + revision_id (str): + The version of the posture, for example, ``c7cfa2a8``. + posture_deployment_resource (str): + The project, folder, or organization on which the posture is + deployed, for example, ``projects/{project_number}``. + posture_deployment (str): + The name of the posture deployment, for example, + ``organizations/{org_id}/posturedeployments/{posture_deployment_id}``. + changed_policy (str): + The name of the updated policy, for example, + ``projects/{project_id}/policies/{constraint_name}``. + policy_set (str): + The name of the updated policy set, for example, + ``cis-policyset``. + policy (str): + The ID of the updated policy, for example, + ``compute-policy-1``. + policy_drift_details (MutableSequence[google.cloud.securitycenter_v2.types.SecurityPosture.PolicyDriftDetails]): + The details about a change in an updated + policy that violates the deployed posture. + """ + + class PolicyDriftDetails(proto.Message): + r"""The policy field that violates the deployed posture and its + expected and detected values. + + Attributes: + field (str): + The name of the updated field, for example + constraint.implementation.policy_rules[0].enforce + expected_value (str): + The value of this field that was configured in a posture, + for example, ``true`` or + ``allowed_values={"projects/29831892"}``. + detected_value (str): + The detected value that violates the deployed posture, for + example, ``false`` or + ``allowed_values={"projects/22831892"}``. + """ + + field: str = proto.Field( + proto.STRING, + number=1, + ) + expected_value: str = proto.Field( + proto.STRING, + number=2, + ) + detected_value: str = proto.Field( + proto.STRING, + number=3, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + revision_id: str = proto.Field( + proto.STRING, + number=2, + ) + posture_deployment_resource: str = proto.Field( + proto.STRING, + number=3, + ) + posture_deployment: str = proto.Field( + proto.STRING, + number=4, + ) + changed_policy: str = proto.Field( + proto.STRING, + number=5, + ) + policy_set: str = proto.Field( + proto.STRING, + number=6, + ) + policy: str = proto.Field( + proto.STRING, + number=7, + ) + policy_drift_details: MutableSequence[PolicyDriftDetails] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=PolicyDriftDetails, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/securitycenter_service.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/securitycenter_service.py new file mode 100644 index 000000000000..f5465ae463ed --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/securitycenter_service.py @@ -0,0 +1,1838 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore +import proto # type: ignore + +from google.cloud.securitycenter_v2.types import external_system as gcs_external_system +from google.cloud.securitycenter_v2.types import ( + notification_config as gcs_notification_config, +) +from google.cloud.securitycenter_v2.types import ( + resource_value_config as gcs_resource_value_config, +) +from google.cloud.securitycenter_v2.types import security_marks as gcs_security_marks +from google.cloud.securitycenter_v2.types import attack_path, bigquery_export +from google.cloud.securitycenter_v2.types import finding as gcs_finding +from google.cloud.securitycenter_v2.types import mute_config as gcs_mute_config +from google.cloud.securitycenter_v2.types import source as gcs_source +from google.cloud.securitycenter_v2.types import valued_resource + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "BatchCreateResourceValueConfigsRequest", + "BatchCreateResourceValueConfigsResponse", + "BulkMuteFindingsRequest", + "BulkMuteFindingsResponse", + "CreateBigQueryExportRequest", + "CreateFindingRequest", + "CreateMuteConfigRequest", + "CreateNotificationConfigRequest", + "CreateResourceValueConfigRequest", + "CreateSourceRequest", + "DeleteBigQueryExportRequest", + "DeleteMuteConfigRequest", + "DeleteNotificationConfigRequest", + "DeleteResourceValueConfigRequest", + "GetBigQueryExportRequest", + "GetMuteConfigRequest", + "GetNotificationConfigRequest", + "GetResourceValueConfigRequest", + "GetSourceRequest", + "GroupFindingsRequest", + "GroupFindingsResponse", + "GroupResult", + "ListAttackPathsRequest", + "ListAttackPathsResponse", + "GetSimulationRequest", + "GetValuedResourceRequest", + "ListBigQueryExportsRequest", + "ListBigQueryExportsResponse", + "ListFindingsRequest", + "ListFindingsResponse", + "ListMuteConfigsRequest", + "ListMuteConfigsResponse", + "ListNotificationConfigsRequest", + "ListNotificationConfigsResponse", + "ListResourceValueConfigsRequest", + "ListResourceValueConfigsResponse", + "ListSourcesRequest", + "ListSourcesResponse", + "ListValuedResourcesRequest", + "ListValuedResourcesResponse", + "SetFindingStateRequest", + "SetMuteRequest", + "UpdateBigQueryExportRequest", + "UpdateExternalSystemRequest", + "UpdateFindingRequest", + "UpdateMuteConfigRequest", + "UpdateNotificationConfigRequest", + "UpdateResourceValueConfigRequest", + "UpdateSecurityMarksRequest", + "UpdateSourceRequest", + }, +) + + +class BatchCreateResourceValueConfigsRequest(proto.Message): + r"""Request message to create multiple resource value configs + + Attributes: + parent (str): + Required. Resource name of the new + ResourceValueConfig's parent. The parent field + in the CreateResourceValueConfigRequest messages + must either be empty or match this field. + requests (MutableSequence[google.cloud.securitycenter_v2.types.CreateResourceValueConfigRequest]): + Required. The resource value configs to be + created. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["CreateResourceValueConfigRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="CreateResourceValueConfigRequest", + ) + + +class BatchCreateResourceValueConfigsResponse(proto.Message): + r"""Response message for BatchCreateResourceValueConfigs + + Attributes: + resource_value_configs (MutableSequence[google.cloud.securitycenter_v2.types.ResourceValueConfig]): + The resource value configs created + """ + + resource_value_configs: MutableSequence[ + gcs_resource_value_config.ResourceValueConfig + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcs_resource_value_config.ResourceValueConfig, + ) + + +class BulkMuteFindingsRequest(proto.Message): + r"""Request message for bulk findings update. + + Note: + + 1. If multiple bulk update requests match the same resource, the + order in which they get executed is not defined. + 2. Once a bulk operation is started, there is no way to stop it. + + Attributes: + parent (str): + Required. The parent, at which bulk action needs to be + applied. If no location is specified, findings are updated + in global. The following list shows some examples: + + - ``organizations/[organization_id]`` + - ``organizations/[organization_id]/locations/[location_id]`` + - ``folders/[folder_id]`` + - ``folders/[folder_id]/locations/[location_id]`` + - ``projects/[project_id]`` + - ``projects/[project_id]/locations/[location_id]`` + filter (str): + Expression that identifies findings that should be updated. + The expression is a list of zero or more restrictions + combined via logical operators ``AND`` and ``OR``. + Parentheses are supported, and ``OR`` has higher precedence + than ``AND``. + + Restrictions have the form `` `` + and may have a ``-`` character in front of them to indicate + negation. The fields map to those defined in the + corresponding resource. + + The supported operators are: + + - ``=`` for all value types. + - ``>``, ``<``, ``>=``, ``<=`` for integer values. + - ``:``, meaning substring matching, for strings. + + The supported value types are: + + - string literals in quotes. + - integer literals without quotes. + - boolean literals ``true`` and ``false`` without quotes. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + + +class BulkMuteFindingsResponse(proto.Message): + r"""The response to a BulkMute request. Contains the LRO + information. + + """ + + +class CreateBigQueryExportRequest(proto.Message): + r"""Request message for creating a BigQuery export. + + Attributes: + parent (str): + Required. The name of the parent resource of the new + BigQuery export. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + big_query_export (google.cloud.securitycenter_v2.types.BigQueryExport): + Required. The BigQuery export being created. + big_query_export_id (str): + Required. Unique identifier provided by the + client within the parent scope. It must consist + of only lowercase letters, numbers, and hyphens, + must start with a letter, must end with either a + letter or a number, and must be 63 characters or + less. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + big_query_export: bigquery_export.BigQueryExport = proto.Field( + proto.MESSAGE, + number=2, + message=bigquery_export.BigQueryExport, + ) + big_query_export_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class CreateFindingRequest(proto.Message): + r"""Request message for creating a finding. + + Attributes: + parent (str): + Required. Resource name of the new finding's parent. The + following list shows some examples of the format: + + ``organizations/[organization_id]/sources/[source_id]`` + + ``organizations/[organization_id]/sources/[source_id]/locations/[location_id]`` + finding_id (str): + Required. Unique identifier provided by the + client within the parent scope. It must be + alphanumeric and less than or equal to 32 + characters and greater than 0 characters in + length. + finding (google.cloud.securitycenter_v2.types.Finding): + Required. The Finding being created. The name and + security_marks will be ignored as they are both output only + fields on this resource. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + finding_id: str = proto.Field( + proto.STRING, + number=2, + ) + finding: gcs_finding.Finding = proto.Field( + proto.MESSAGE, + number=3, + message=gcs_finding.Finding, + ) + + +class CreateMuteConfigRequest(proto.Message): + r"""Request message for creating a mute config. + + Attributes: + parent (str): + Required. Resource name of the new mute configs's parent. + Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + mute_config (google.cloud.securitycenter_v2.types.MuteConfig): + Required. The mute config being created. + mute_config_id (str): + Required. Unique identifier provided by the + client within the parent scope. It must consist + of only lowercase letters, numbers, and hyphens, + must start with a letter, must end with either a + letter or a number, and must be 63 characters or + less. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + mute_config: gcs_mute_config.MuteConfig = proto.Field( + proto.MESSAGE, + number=2, + message=gcs_mute_config.MuteConfig, + ) + mute_config_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class CreateNotificationConfigRequest(proto.Message): + r"""Request message for creating a notification config. + + Attributes: + parent (str): + Required. Resource name of the new notification config's + parent. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + config_id (str): + Required. + Unique identifier provided by the client within + the parent scope. It must be between 1 and 128 + characters and contain alphanumeric characters, + underscores, or hyphens only. + notification_config (google.cloud.securitycenter_v2.types.NotificationConfig): + Required. The notification config being + created. The name and the service account will + be ignored as they are both output only fields + on this resource. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + config_id: str = proto.Field( + proto.STRING, + number=2, + ) + notification_config: gcs_notification_config.NotificationConfig = proto.Field( + proto.MESSAGE, + number=3, + message=gcs_notification_config.NotificationConfig, + ) + + +class CreateResourceValueConfigRequest(proto.Message): + r"""Request message to create single resource value config + + Attributes: + parent (str): + Required. Resource name of the new + ResourceValueConfig's parent. + resource_value_config (google.cloud.securitycenter_v2.types.ResourceValueConfig): + Required. The resource value config being + created. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + resource_value_config: gcs_resource_value_config.ResourceValueConfig = proto.Field( + proto.MESSAGE, + number=2, + message=gcs_resource_value_config.ResourceValueConfig, + ) + + +class CreateSourceRequest(proto.Message): + r"""Request message for creating a source. + + Attributes: + parent (str): + Required. Resource name of the new source's parent. Its + format should be "organizations/[organization_id]". + source (google.cloud.securitycenter_v2.types.Source): + Required. The Source being created, only the display_name + and description will be used. All other fields will be + ignored. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + source: gcs_source.Source = proto.Field( + proto.MESSAGE, + number=2, + message=gcs_source.Source, + ) + + +class DeleteBigQueryExportRequest(proto.Message): + r"""Request message for deleting a BigQuery export. + + Attributes: + name (str): + Required. The name of the BigQuery export to delete. The + following list shows some examples of the format: + + - + + ``organizations/{organization}/locations/{location}/bigQueryExports/{export_id}`` + + - ``folders/{folder}/locations/{location}/bigQueryExports/{export_id}`` + - ``projects/{project}/locations/{location}/bigQueryExports/{export_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class DeleteMuteConfigRequest(proto.Message): + r"""Request message for deleting a mute config. If no location is + specified, default is global. + + Attributes: + name (str): + Required. Name of the mute config to delete. The following + list shows some examples of the format: + + - ``organizations/{organization}/muteConfigs/{config_id}`` + - + + ``organizations/{organization}/locations/{location}/muteConfigs/{config_id}`` + + - ``folders/{folder}/muteConfigs/{config_id}`` + - ``folders/{folder}/locations/{location}/muteConfigs/{config_id}`` + - ``projects/{project}/muteConfigs/{config_id}`` + - ``projects/{project}/locations/{location}/muteConfigs/{config_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class DeleteNotificationConfigRequest(proto.Message): + r"""Request message for deleting a notification config. + + Attributes: + name (str): + Required. Name of the notification config to delete. The + following list shows some examples of the format: + + - + + ``organizations/[organization_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + + ``folders/[folder_id]/locations/[location_id]notificationConfigs/[config_id]`` + + + ``projects/[project_id]/locations/[location_id]notificationConfigs/[config_id]`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class DeleteResourceValueConfigRequest(proto.Message): + r"""Request message to delete resource value config + + Attributes: + name (str): + Required. Name of the ResourceValueConfig to + delete + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetBigQueryExportRequest(proto.Message): + r"""Request message for retrieving a BigQuery export. + + Attributes: + name (str): + Required. Name of the BigQuery export to retrieve. The + following list shows some examples of the format: + + - + + ``organizations/{organization}/locations/{location}/bigQueryExports/{export_id}`` + + - ``folders/{folder}/locations/{location}/bigQueryExports/{export_id}`` + - ``projects/{project}locations/{location}//bigQueryExports/{export_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetMuteConfigRequest(proto.Message): + r"""Request message for retrieving a mute config. If no location + is specified, default is global. + + Attributes: + name (str): + Required. Name of the mute config to retrieve. The following + list shows some examples of the format: + + - ``organizations/{organization}/muteConfigs/{config_id}`` + - + + ``organizations/{organization}/locations/{location}/muteConfigs/{config_id}`` + + - ``folders/{folder}/muteConfigs/{config_id}`` + - ``folders/{folder}/locations/{location}/muteConfigs/{config_id}`` + - ``projects/{project}/muteConfigs/{config_id}`` + - ``projects/{project}/locations/{location}/muteConfigs/{config_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetNotificationConfigRequest(proto.Message): + r"""Request message for getting a notification config. + + Attributes: + name (str): + Required. Name of the notification config to get. The + following list shows some examples of the format: + + - + + ``organizations/[organization_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + + ``folders/[folder_id]/locations/[location_id]/notificationConfigs/[config_id]`` + + + ``projects/[project_id]/locations/[location_id]/notificationConfigs/[config_id]`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetResourceValueConfigRequest(proto.Message): + r"""Request message to get resource value config + + Attributes: + name (str): + Required. Name of the resource value config to retrieve. Its + format is + organizations/{organization}/resourceValueConfigs/{config_id}. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetSourceRequest(proto.Message): + r"""Request message for getting a source. + + Attributes: + name (str): + Required. Relative resource name of the source. Its format + is "organizations/[organization_id]/source/[source_id]". + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GroupFindingsRequest(proto.Message): + r"""Request message for grouping by findings. + + Attributes: + parent (str): + Required. Name of the source to groupBy. If no location is + specified, finding is assumed to be in global. The following + list shows some examples: + + - ``organizations/[organization_id]/sources/[source_id]`` + - + + ``organizations/[organization_id]/sources/[source_id]/locations/[location_id]`` + + - ``folders/[folder_id]/sources/[source_id]`` + - ``folders/[folder_id]/sources/[source_id]/locations/[location_id]`` + - ``projects/[project_id]/sources/[source_id]`` + - ``projects/[project_id]/sources/[source_id]/locations/[location_id]`` + + To groupBy across all sources provide a source_id of ``-``. + The following list shows some examples: + + - ``organizations/{organization_id}/sources/-`` + - ``organizations/{organization_id}/sources/-/locations/[location_id]`` + - ``folders/{folder_id}/sources/-`` + - ``folders/{folder_id}/sources/-/locations/[location_id]`` + - ``projects/{project_id}/sources/-`` + - ``projects/{project_id}/sources/-/locations/[location_id]`` + filter (str): + Expression that defines the filter to apply across findings. + The expression is a list of one or more restrictions + combined via logical operators ``AND`` and ``OR``. + Parentheses are supported, and ``OR`` has higher precedence + than ``AND``. + + Restrictions have the form `` `` + and may have a ``-`` character in front of them to indicate + negation. Examples include: + + - name + - security_marks.marks.marka + + The supported operators are: + + - ``=`` for all value types. + - ``>``, ``<``, ``>=``, ``<=`` for integer values. + - ``:``, meaning substring matching, for strings. + + The supported value types are: + + - string literals in quotes. + - integer literals without quotes. + - boolean literals ``true`` and ``false`` without quotes. + + The following field and operator combinations are supported: + + - name: ``=`` + + - parent: ``=``, ``:`` + + - resource_name: ``=``, ``:`` + + - state: ``=``, ``:`` + + - category: ``=``, ``:`` + + - external_uri: ``=``, ``:`` + + - event_time: ``=``, ``>``, ``<``, ``>=``, ``<=`` + + Usage: This should be milliseconds since epoch or an + RFC3339 string. Examples: + ``event_time = "2019-06-10T16:07:18-07:00"`` + ``event_time = 1560208038000`` + + - severity: ``=``, ``:`` + + - security_marks.marks: ``=``, ``:`` + + - resource: + + - resource.name: ``=``, ``:`` + - resource.parent_name: ``=``, ``:`` + - resource.parent_display_name: ``=``, ``:`` + - resource.project_name: ``=``, ``:`` + - resource.project_display_name: ``=``, ``:`` + - resource.type: ``=``, ``:`` + group_by (str): + Required. Expression that defines what assets fields to use + for grouping. The string value should follow SQL syntax: + comma separated list of fields. For example: + "parent,resource_name". + + The following fields are supported: + + - resource_name + - category + - state + - parent + - severity + page_token (str): + The value returned by the last ``GroupFindingsResponse``; + indicates that this is a continuation of a prior + ``GroupFindings`` call, and that the system should return + the next page of data. + page_size (int): + The maximum number of results to return in a + single response. Default is 10, minimum is 1, + maximum is 1000. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + group_by: str = proto.Field( + proto.STRING, + number=3, + ) + page_token: str = proto.Field( + proto.STRING, + number=7, + ) + page_size: int = proto.Field( + proto.INT32, + number=8, + ) + + +class GroupFindingsResponse(proto.Message): + r"""Response message for group by findings. + + Attributes: + group_by_results (MutableSequence[google.cloud.securitycenter_v2.types.GroupResult]): + Group results. There exists an element for + each existing unique combination of + property/values. The element contains a count + for the number of times those specific + property/values appear. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results. + total_size (int): + The total number of results matching the + query. + """ + + @property + def raw_page(self): + return self + + group_by_results: MutableSequence["GroupResult"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GroupResult", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=3, + ) + total_size: int = proto.Field( + proto.INT32, + number=4, + ) + + +class GroupResult(proto.Message): + r"""Result containing the properties and count of a groupBy + request. + + Attributes: + properties (MutableMapping[str, google.protobuf.struct_pb2.Value]): + Properties matching the groupBy fields in the + request. + count (int): + Total count of resources for the given + properties. + """ + + properties: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=1, + message=struct_pb2.Value, + ) + count: int = proto.Field( + proto.INT64, + number=2, + ) + + +class ListAttackPathsRequest(proto.Message): + r"""Request message for listing the attack paths for a given + simulation or valued resource. + + Attributes: + parent (str): + Required. Name of parent to list attack paths. + + Valid formats: "organizations/{organization}", + "organizations/{organization}/simulations/{simulation}" + "organizations/{organization}/simulations/{simulation}/attackExposureResults/{attack_exposure_result_v2}" + "organizations/{organization}/simulations/{simulation}/valuedResources/{valued_resource}". + filter (str): + The filter expression that filters the attack path in the + response. Supported fields: + + - ``valued_resources`` supports = + page_token (str): + The value returned by the last ``ListAttackPathsResponse``; + indicates that this is a continuation of a prior + ``ListAttackPaths`` call, and that the system should return + the next page of data. + page_size (int): + The maximum number of results to return in a + single response. Default is 10, minimum is 1, + maximum is 1000. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + page_size: int = proto.Field( + proto.INT32, + number=4, + ) + + +class ListAttackPathsResponse(proto.Message): + r"""Response message for listing the attack paths for a given + simulation or valued resource. + + Attributes: + attack_paths (MutableSequence[google.cloud.securitycenter_v2.types.AttackPath]): + The attack paths that the attack path + simulation identified. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results. + """ + + @property + def raw_page(self): + return self + + attack_paths: MutableSequence[attack_path.AttackPath] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=attack_path.AttackPath, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetSimulationRequest(proto.Message): + r"""Request message for getting simulation. + Simulation name can include "latest" to retrieve the latest + simulation For example, "organizations/123/simulations/latest" + + Attributes: + name (str): + Required. The organization name or simulation + name of this simulation + Valid format: + + "organizations/{organization}/simulations/latest" + "organizations/{organization}/simulations/{simulation}". + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetValuedResourceRequest(proto.Message): + r"""Request message for getting a valued resource. + + Attributes: + name (str): + Required. The name of this valued resource + + Valid format: + "organizations/{organization}/simulations/{simulation}/valuedResources/{valued_resource}". + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListBigQueryExportsRequest(proto.Message): + r"""Request message for listing BigQuery exports at a given scope + e.g. organization, folder or project. + + Attributes: + parent (str): + Required. The parent, which owns the collection of BigQuery + exports. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + page_size (int): + The maximum number of configs to return. The + service may return fewer than this value. + If unspecified, at most 10 configs will be + returned. The maximum value is 1000; values + above 1000 will be coerced to 1000. + page_token (str): + A page token, received from a previous + ``ListBigQueryExports`` call. Provide this to retrieve the + subsequent page. When paginating, all other parameters + provided to ``ListBigQueryExports`` must match the call that + provided the page token. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListBigQueryExportsResponse(proto.Message): + r"""Response message for listing BigQuery exports. + + Attributes: + big_query_exports (MutableSequence[google.cloud.securitycenter_v2.types.BigQueryExport]): + The BigQuery exports from the specified + parent. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + big_query_exports: MutableSequence[ + bigquery_export.BigQueryExport + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=bigquery_export.BigQueryExport, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ListFindingsRequest(proto.Message): + r"""Request message for listing findings. + + Attributes: + parent (str): + Required. Name of the source the findings belong to. If no + location is specified, the default is global. The following + list shows some examples: + + - ``organizations/[organization_id]/sources/[source_id]`` + - + + ``organizations/[organization_id]/sources/[source_id]/locations/[location_id]`` + + - ``folders/[folder_id]/sources/[source_id]`` + - ``folders/[folder_id]/sources/[source_id]/locations/[location_id]`` + - ``projects/[project_id]/sources/[source_id]`` + - ``projects/[project_id]/sources/[source_id]/locations/[location_id]`` + + To list across all sources provide a source_id of ``-``. The + following list shows some examples: + + - ``organizations/{organization_id}/sources/-`` + - ``organizations/{organization_id}/sources/-/locations/{location_id}`` + - ``folders/{folder_id}/sources/-`` + - ``folders/{folder_id}/sources/-locations/{location_id}`` + - ``projects/{projects_id}/sources/-`` + - ``projects/{projects_id}/sources/-/locations/{location_id}`` + filter (str): + Expression that defines the filter to apply across findings. + The expression is a list of one or more restrictions + combined via logical operators ``AND`` and ``OR``. + Parentheses are supported, and ``OR`` has higher precedence + than ``AND``. + + Restrictions have the form `` `` + and may have a ``-`` character in front of them to indicate + negation. Examples include: + + - name + - security_marks.marks.marka + + The supported operators are: + + - ``=`` for all value types. + - ``>``, ``<``, ``>=``, ``<=`` for integer values. + - ``:``, meaning substring matching, for strings. + + The supported value types are: + + - string literals in quotes. + - integer literals without quotes. + - boolean literals ``true`` and ``false`` without quotes. + + The following field and operator combinations are supported: + + - name: ``=`` + + - parent: ``=``, ``:`` + + - resource_name: ``=``, ``:`` + + - state: ``=``, ``:`` + + - category: ``=``, ``:`` + + - external_uri: ``=``, ``:`` + + - event_time: ``=``, ``>``, ``<``, ``>=``, ``<=`` + + Usage: This should be milliseconds since epoch or an + RFC3339 string. Examples: + ``event_time = "2019-06-10T16:07:18-07:00"`` + ``event_time = 1560208038000`` + + - severity: ``=``, ``:`` + + - security_marks.marks: ``=``, ``:`` + + - resource: + + - resource.name: ``=``, ``:`` + - resource.parent_name: ``=``, ``:`` + - resource.parent_display_name: ``=``, ``:`` + - resource.project_name: ``=``, ``:`` + - resource.project_display_name: ``=``, ``:`` + - resource.type: ``=``, ``:`` + - resource.folders.resource_folder: ``=``, ``:`` + - resource.display_name: ``=``, ``:`` + order_by (str): + Expression that defines what fields and order to use for + sorting. The string value should follow SQL syntax: comma + separated list of fields. For example: "name,parent". The + default sorting order is ascending. To specify descending + order for a field, a suffix " desc" should be appended to + the field name. For example: "name desc,parent". Redundant + space characters in the syntax are insignificant. "name + desc,parent" and " name desc , parent " are equivalent. + + The following fields are supported: name parent state + category resource_name event_time security_marks.marks + field_mask (google.protobuf.field_mask_pb2.FieldMask): + A field mask to specify the Finding fields to + be listed in the response. An empty field mask + will list all fields. + page_token (str): + The value returned by the last ``ListFindingsResponse``; + indicates that this is a continuation of a prior + ``ListFindings`` call, and that the system should return the + next page of data. + page_size (int): + The maximum number of results to return in a + single response. Default is 10, minimum is 1, + maximum is 1000. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + order_by: str = proto.Field( + proto.STRING, + number=3, + ) + field_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=7, + message=field_mask_pb2.FieldMask, + ) + page_token: str = proto.Field( + proto.STRING, + number=8, + ) + page_size: int = proto.Field( + proto.INT32, + number=9, + ) + + +class ListFindingsResponse(proto.Message): + r"""Response message for listing findings. + + Attributes: + list_findings_results (MutableSequence[google.cloud.securitycenter_v2.types.ListFindingsResponse.ListFindingsResult]): + Findings matching the list request. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results. + total_size (int): + The total number of findings matching the + query. + """ + + class ListFindingsResult(proto.Message): + r"""Result containing the Finding. + + Attributes: + finding (google.cloud.securitycenter_v2.types.Finding): + Finding matching the search request. + resource (google.cloud.securitycenter_v2.types.ListFindingsResponse.ListFindingsResult.Resource): + Output only. Resource that is associated with + this finding. + """ + + class Resource(proto.Message): + r"""Information related to the Google Cloud resource that is + associated with this finding. + + Attributes: + name (str): + The full resource name of the resource. See: + https://cloud.google.com/apis/design/resource_names#full_resource_name + display_name (str): + The human readable name of the resource. + type_ (str): + The full resource type of the resource. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + type_: str = proto.Field( + proto.STRING, + number=3, + ) + + finding: gcs_finding.Finding = proto.Field( + proto.MESSAGE, + number=1, + message=gcs_finding.Finding, + ) + resource: "ListFindingsResponse.ListFindingsResult.Resource" = proto.Field( + proto.MESSAGE, + number=3, + message="ListFindingsResponse.ListFindingsResult.Resource", + ) + + @property + def raw_page(self): + return self + + list_findings_results: MutableSequence[ListFindingsResult] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=ListFindingsResult, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=3, + ) + total_size: int = proto.Field( + proto.INT32, + number=4, + ) + + +class ListMuteConfigsRequest(proto.Message): + r"""Request message for listing mute configs at a given scope + e.g. organization, folder or project. If no location is + specified, default is global. + + Attributes: + parent (str): + Required. The parent, which owns the collection of mute + configs. Its format is "organizations/[organization_id]", + "folders/[folder_id]", "projects/[project_id]", + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", + "projects/[project_id]/locations/[location_id]". + page_size (int): + The maximum number of configs to return. The + service may return fewer than this value. + If unspecified, at most 10 configs will be + returned. The maximum value is 1000; values + above 1000 will be coerced to 1000. + page_token (str): + A page token, received from a previous ``ListMuteConfigs`` + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + ``ListMuteConfigs`` must match the call that provided the + page token. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListMuteConfigsResponse(proto.Message): + r"""Response message for listing mute configs. + + Attributes: + mute_configs (MutableSequence[google.cloud.securitycenter_v2.types.MuteConfig]): + The mute configs from the specified parent. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + mute_configs: MutableSequence[gcs_mute_config.MuteConfig] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcs_mute_config.MuteConfig, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ListNotificationConfigsRequest(proto.Message): + r"""Request message for listing notification configs. + + Attributes: + parent (str): + Required. The name of the parent in which to list the + notification configurations. Its format is + "organizations/[organization_id]/locations/[location_id]", + "folders/[folder_id]/locations/[location_id]", or + "projects/[project_id]/locations/[location_id]". + page_token (str): + The value returned by the last + ``ListNotificationConfigsResponse``; indicates that this is + a continuation of a prior ``ListNotificationConfigs`` call, + and that the system should return the next page of data. + page_size (int): + The maximum number of results to return in a + single response. Default is 10, minimum is 1, + maximum is 1000. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_token: str = proto.Field( + proto.STRING, + number=2, + ) + page_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +class ListNotificationConfigsResponse(proto.Message): + r"""Response message for listing notification configs. + + Attributes: + notification_configs (MutableSequence[google.cloud.securitycenter_v2.types.NotificationConfig]): + Notification configs belonging to the + requested parent. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results. + """ + + @property + def raw_page(self): + return self + + notification_configs: MutableSequence[ + gcs_notification_config.NotificationConfig + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcs_notification_config.NotificationConfig, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ListResourceValueConfigsRequest(proto.Message): + r"""Request message to list resource value configs of a parent + + Attributes: + parent (str): + Required. The parent, which owns the collection of resource + value configs. Its format is + "organizations/[organization_id]". + page_size (int): + The maximum number of configs to return. The + service may return fewer than this value. + If unspecified, at most 10 configs will be + returned. The maximum value is 1000; values + above 1000 will be coerced to 1000. + page_token (str): + A page token, received from a previous + ``ListResourceValueConfigs`` call. Provide this to retrieve + the subsequent page. + + When paginating, all other parameters provided to + ``ListResourceValueConfigs`` must match the call that + provided the page token. + + page_size can be specified, and the new page_size will be + used. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListResourceValueConfigsResponse(proto.Message): + r"""Response message to list resource value configs + + Attributes: + resource_value_configs (MutableSequence[google.cloud.securitycenter_v2.types.ResourceValueConfig]): + The resource value configs from the specified + parent. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is empty, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + resource_value_configs: MutableSequence[ + gcs_resource_value_config.ResourceValueConfig + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcs_resource_value_config.ResourceValueConfig, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ListSourcesRequest(proto.Message): + r"""Request message for listing sources. + + Attributes: + parent (str): + Required. Resource name of the parent of sources to list. + Its format should be "organizations/[organization_id]", + "folders/[folder_id]", or "projects/[project_id]". + page_token (str): + The value returned by the last ``ListSourcesResponse``; + indicates that this is a continuation of a prior + ``ListSources`` call, and that the system should return the + next page of data. + page_size (int): + The maximum number of results to return in a + single response. Default is 10, minimum is 1, + maximum is 1000. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_token: str = proto.Field( + proto.STRING, + number=2, + ) + page_size: int = proto.Field( + proto.INT32, + number=7, + ) + + +class ListSourcesResponse(proto.Message): + r"""Response message for listing sources. + + Attributes: + sources (MutableSequence[google.cloud.securitycenter_v2.types.Source]): + Sources belonging to the requested parent. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results. + """ + + @property + def raw_page(self): + return self + + sources: MutableSequence[gcs_source.Source] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcs_source.Source, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ListValuedResourcesRequest(proto.Message): + r"""Request message for listing the valued resources for a given + simulation. + + Attributes: + parent (str): + Required. Name of parent to list exposed resources. + + Valid formats: "organizations/{organization}", + "organizations/{organization}/simulations/{simulation}" + "organizations/{organization}/simulations/{simulation}/attackExposureResults/{attack_exposure_result_v2}". + filter (str): + The filter expression that filters the valued resources in + the response. Supported fields: + + - ``resource_value`` supports = + - ``resource_type`` supports = + page_token (str): + The value returned by the last + ``ListValuedResourcesResponse``; indicates that this is a + continuation of a prior ``ListValuedResources`` call, and + that the system should return the next page of data. + page_size (int): + The maximum number of results to return in a + single response. Default is 10, minimum is 1, + maximum is 1000. + order_by (str): + Optional. The fields by which to order the valued resources + response. + + Supported fields: + + - ``exposed_score`` + + - ``resource_value`` + + - ``resource_type`` + + Values should be a comma separated list of fields. For + example: ``exposed_score,resource_value``. + + The default sorting order is descending. To specify + ascending or descending order for a field, append a " ASC" + or a " DESC" suffix, respectively; for example: + ``exposed_score DESC``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + page_size: int = proto.Field( + proto.INT32, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + + +class ListValuedResourcesResponse(proto.Message): + r"""Response message for listing the valued resources for a given + simulation. + + Attributes: + valued_resources (MutableSequence[google.cloud.securitycenter_v2.types.ValuedResource]): + The valued resources that the attack path + simulation identified. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results. + total_size (int): + The estimated total number of results + matching the query. + """ + + @property + def raw_page(self): + return self + + valued_resources: MutableSequence[ + valued_resource.ValuedResource + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=valued_resource.ValuedResource, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +class SetFindingStateRequest(proto.Message): + r"""Request message for updating a finding's state. + + Attributes: + name (str): + Required. The `relative resource + name `__ + of the finding. If no location is specified, finding is + assumed to be in global. The following list shows some + examples: + + - + + ``organizations/{organization_id}/sources/{source_id}/findings/{finding_id}`` + + + ``organizations/{organization_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``folders/{folder_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``folders/{folder_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``projects/{project_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``projects/{project_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + state (google.cloud.securitycenter_v2.types.Finding.State): + Required. The desired State of the finding. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + state: gcs_finding.Finding.State = proto.Field( + proto.ENUM, + number=2, + enum=gcs_finding.Finding.State, + ) + + +class SetMuteRequest(proto.Message): + r"""Request message for updating a finding's mute status. + + Attributes: + name (str): + Required. The `relative resource + name `__ + of the finding. If no location is specified, finding is + assumed to be in global. The following list shows some + examples: + + - + + ``organizations/{organization_id}/sources/{source_id}/findings/{finding_id}`` + + + ``organizations/{organization_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``folders/{folder_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``folders/{folder_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + + - ``projects/{project_id}/sources/{source_id}/findings/{finding_id}`` + - + + ``projects/{project_id}/sources/{source_id}/locations/{location_id}/findings/{finding_id}`` + mute (google.cloud.securitycenter_v2.types.Finding.Mute): + Required. The desired state of the Mute. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + mute: gcs_finding.Finding.Mute = proto.Field( + proto.ENUM, + number=2, + enum=gcs_finding.Finding.Mute, + ) + + +class UpdateBigQueryExportRequest(proto.Message): + r"""Request message for updating a BigQuery export. + + Attributes: + big_query_export (google.cloud.securitycenter_v2.types.BigQueryExport): + Required. The BigQuery export being updated. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The list of fields to be updated. + If empty all mutable fields will be updated. + """ + + big_query_export: bigquery_export.BigQueryExport = proto.Field( + proto.MESSAGE, + number=1, + message=bigquery_export.BigQueryExport, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class UpdateExternalSystemRequest(proto.Message): + r"""Request message for updating a ExternalSystem resource. + + Attributes: + external_system (google.cloud.securitycenter_v2.types.ExternalSystem): + Required. The external system resource to + update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask to use when updating the + external system resource. + If empty all mutable fields will be updated. + """ + + external_system: gcs_external_system.ExternalSystem = proto.Field( + proto.MESSAGE, + number=1, + message=gcs_external_system.ExternalSystem, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class UpdateFindingRequest(proto.Message): + r"""Request message for updating or creating a finding. + + Attributes: + finding (google.cloud.securitycenter_v2.types.Finding): + Required. The finding resource to update or create if it + does not already exist. parent, security_marks, and + update_time will be ignored. + + In the case of creation, the finding id portion of the name + must be alphanumeric and less than or equal to 32 characters + and greater than 0 characters in length. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask to use when updating the finding resource. + This field should not be specified when creating a finding. + + When updating a finding, an empty mask is treated as + updating all mutable fields and replacing source_properties. + Individual source_properties can be added/updated by using + "source_properties." in the field mask. + """ + + finding: gcs_finding.Finding = proto.Field( + proto.MESSAGE, + number=1, + message=gcs_finding.Finding, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class UpdateMuteConfigRequest(proto.Message): + r"""Request message for updating a mute config. + + Attributes: + mute_config (google.cloud.securitycenter_v2.types.MuteConfig): + Required. The mute config being updated. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The list of fields to be updated. + If empty all mutable fields will be updated. + """ + + mute_config: gcs_mute_config.MuteConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcs_mute_config.MuteConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class UpdateNotificationConfigRequest(proto.Message): + r"""Request message for updating a notification config. + + Attributes: + notification_config (google.cloud.securitycenter_v2.types.NotificationConfig): + Required. The notification config to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask to use when updating the + notification config. + If empty all mutable fields will be updated. + """ + + notification_config: gcs_notification_config.NotificationConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcs_notification_config.NotificationConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class UpdateResourceValueConfigRequest(proto.Message): + r"""Request message to update resource value config + + Attributes: + resource_value_config (google.cloud.securitycenter_v2.types.ResourceValueConfig): + Required. The resource value config being + updated. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The list of fields to be updated. + If empty all mutable fields will be updated. + """ + + resource_value_config: gcs_resource_value_config.ResourceValueConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcs_resource_value_config.ResourceValueConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class UpdateSecurityMarksRequest(proto.Message): + r"""Request message for updating a SecurityMarks resource. + + Attributes: + security_marks (google.cloud.securitycenter_v2.types.SecurityMarks): + Required. The security marks resource to + update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask to use when updating the security marks + resource. + + The field mask must not contain duplicate fields. If empty + or set to "marks", all marks will be replaced. Individual + marks can be updated using "marks.". + """ + + security_marks: gcs_security_marks.SecurityMarks = proto.Field( + proto.MESSAGE, + number=1, + message=gcs_security_marks.SecurityMarks, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class UpdateSourceRequest(proto.Message): + r"""Request message for updating a source. + + Attributes: + source (google.cloud.securitycenter_v2.types.Source): + Required. The source resource to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The FieldMask to use when updating the source + resource. + If empty all mutable fields will be updated. + """ + + source: gcs_source.Source = proto.Field( + proto.MESSAGE, + number=1, + message=gcs_source.Source, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/simulation.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/simulation.py new file mode 100644 index 000000000000..495fa2590c3a --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/simulation.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +from google.cloud.securitycenter_v2.types import valued_resource + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Simulation", + }, +) + + +class Simulation(proto.Message): + r"""Attack path simulation + + Attributes: + name (str): + Full resource name of the Simulation: + + organizations/123/simulations/456 + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Time simulation was created + resource_value_configs_metadata (MutableSequence[google.cloud.securitycenter_v2.types.ResourceValueConfigMetadata]): + Resource value configurations' metadata used + in this simulation. Maximum of 100. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + resource_value_configs_metadata: MutableSequence[ + valued_resource.ResourceValueConfigMetadata + ] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=valued_resource.ResourceValueConfigMetadata, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/source.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/source.py new file mode 100644 index 000000000000..e1dc3b2592c9 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/source.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Source", + }, +) + + +class Source(proto.Message): + r"""Security Command Center finding source. A finding source + is an entity or a mechanism that can produce a finding. A source + is like a container of findings that come from the same scanner, + logger, monitor, and other tools. + + Attributes: + name (str): + The relative resource name of this source. See: + https://cloud.google.com/apis/design/resource_names#relative_resource_name + Example: + "organizations/{organization_id}/sources/{source_id}". + display_name (str): + The source's display name. + A source's display name must be unique amongst + its siblings, for example, two sources with the + same parent can't share the same display name. + The display name must have a length between 1 + and 64 characters (inclusive). + description (str): + The description of the source (max of 1024 + characters). Example: + + "Web Security Scanner is a web security scanner + for common vulnerabilities in App Engine + applications. It can automatically scan and + detect four common vulnerabilities, including + cross-site-scripting (XSS), Flash injection, + mixed content (HTTP in HTTPS), and outdated or + insecure libraries.". + canonical_name (str): + The canonical name of the finding source. It's either + "organizations/{organization_id}/sources/{source_id}", + "folders/{folder_id}/sources/{source_id}", or + "projects/{project_number}/sources/{source_id}", depending + on the closest CRM ancestor of the resource associated with + the finding. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + canonical_name: str = proto.Field( + proto.STRING, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/valued_resource.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/valued_resource.py new file mode 100644 index 000000000000..0f347496e1a9 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/valued_resource.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "ValuedResource", + "ResourceValueConfigMetadata", + }, +) + + +class ValuedResource(proto.Message): + r"""A resource that is determined to have value to a user's + system + + Attributes: + name (str): + Valued resource name, for example, e.g.: + ``organizations/123/simulations/456/valuedResources/789`` + resource (str): + The `full resource + name `__ + of the valued resource. + resource_type (str): + The `resource + type `__ + of the valued resource. + display_name (str): + Human-readable name of the valued resource. + resource_value (google.cloud.securitycenter_v2.types.ValuedResource.ResourceValue): + How valuable this resource is. + exposed_score (float): + Exposed score for this valued resource. A + value of 0 means no exposure was detected + exposure. + resource_value_configs_used (MutableSequence[google.cloud.securitycenter_v2.types.ResourceValueConfigMetadata]): + List of resource value configurations' + metadata used to determine the value of this + resource. Maximum of 100. + """ + + class ResourceValue(proto.Enum): + r"""How valuable the resource is. + + Values: + RESOURCE_VALUE_UNSPECIFIED (0): + The resource value isn't specified. + RESOURCE_VALUE_LOW (1): + This is a low-value resource. + RESOURCE_VALUE_MEDIUM (2): + This is a medium-value resource. + RESOURCE_VALUE_HIGH (3): + This is a high-value resource. + """ + RESOURCE_VALUE_UNSPECIFIED = 0 + RESOURCE_VALUE_LOW = 1 + RESOURCE_VALUE_MEDIUM = 2 + RESOURCE_VALUE_HIGH = 3 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + resource: str = proto.Field( + proto.STRING, + number=2, + ) + resource_type: str = proto.Field( + proto.STRING, + number=3, + ) + display_name: str = proto.Field( + proto.STRING, + number=4, + ) + resource_value: ResourceValue = proto.Field( + proto.ENUM, + number=5, + enum=ResourceValue, + ) + exposed_score: float = proto.Field( + proto.DOUBLE, + number=6, + ) + resource_value_configs_used: MutableSequence[ + "ResourceValueConfigMetadata" + ] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message="ResourceValueConfigMetadata", + ) + + +class ResourceValueConfigMetadata(proto.Message): + r"""Metadata about a ResourceValueConfig. For example, id and + name. + + Attributes: + name (str): + Resource value config name + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/vulnerability.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/vulnerability.py new file mode 100644 index 000000000000..dd04b11ce728 --- /dev/null +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v2/types/vulnerability.py @@ -0,0 +1,538 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v2", + manifest={ + "Vulnerability", + "Cve", + "Reference", + "Cvssv3", + "Package", + "SecurityBulletin", + }, +) + + +class Vulnerability(proto.Message): + r"""Refers to common vulnerability fields e.g. cve, cvss, cwe + etc. + + Attributes: + cve (google.cloud.securitycenter_v2.types.Cve): + CVE stands for Common Vulnerabilities and + Exposures (https://cve.mitre.org/about/) + offending_package (google.cloud.securitycenter_v2.types.Package): + The offending package is relevant to the + finding. + fixed_package (google.cloud.securitycenter_v2.types.Package): + The fixed package is relevant to the finding. + security_bulletin (google.cloud.securitycenter_v2.types.SecurityBulletin): + The security bulletin is relevant to this + finding. + """ + + cve: "Cve" = proto.Field( + proto.MESSAGE, + number=1, + message="Cve", + ) + offending_package: "Package" = proto.Field( + proto.MESSAGE, + number=2, + message="Package", + ) + fixed_package: "Package" = proto.Field( + proto.MESSAGE, + number=3, + message="Package", + ) + security_bulletin: "SecurityBulletin" = proto.Field( + proto.MESSAGE, + number=4, + message="SecurityBulletin", + ) + + +class Cve(proto.Message): + r"""CVE stands for Common Vulnerabilities and Exposures. Information + from the `CVE + record `__ that + describes this vulnerability. + + Attributes: + id (str): + The unique identifier for the vulnerability. + e.g. CVE-2021-34527 + references (MutableSequence[google.cloud.securitycenter_v2.types.Reference]): + Additional information about the CVE. + e.g. + https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-34527 + cvssv3 (google.cloud.securitycenter_v2.types.Cvssv3): + Describe Common Vulnerability Scoring System + specified at + https://www.first.org/cvss/v3.1/specification-document + upstream_fix_available (bool): + Whether upstream fix is available for the + CVE. + impact (google.cloud.securitycenter_v2.types.Cve.RiskRating): + The potential impact of the vulnerability if + it was to be exploited. + exploitation_activity (google.cloud.securitycenter_v2.types.Cve.ExploitationActivity): + The exploitation activity of the + vulnerability in the wild. + observed_in_the_wild (bool): + Whether or not the vulnerability has been + observed in the wild. + zero_day (bool): + Whether or not the vulnerability was zero day + when the finding was published. + """ + + class RiskRating(proto.Enum): + r"""The possible values of impact of the vulnerability if it was + to be exploited. + + Values: + RISK_RATING_UNSPECIFIED (0): + Invalid or empty value. + LOW (1): + Exploitation would have little to no security + impact. + MEDIUM (2): + Exploitation would enable attackers to + perform activities, or could allow attackers to + have a direct impact, but would require + additional steps. + HIGH (3): + Exploitation would enable attackers to have a + notable direct impact without needing to + overcome any major mitigating factors. + CRITICAL (4): + Exploitation would fundamentally undermine + the security of affected systems, enable actors + to perform significant attacks with minimal + effort, with little to no mitigating factors to + overcome. + """ + RISK_RATING_UNSPECIFIED = 0 + LOW = 1 + MEDIUM = 2 + HIGH = 3 + CRITICAL = 4 + + class ExploitationActivity(proto.Enum): + r"""The possible values of exploitation activity of the + vulnerability in the wild. + + Values: + EXPLOITATION_ACTIVITY_UNSPECIFIED (0): + Invalid or empty value. + WIDE (1): + Exploitation has been reported or confirmed + to widely occur. + CONFIRMED (2): + Limited reported or confirmed exploitation + activities. + AVAILABLE (3): + Exploit is publicly available. + ANTICIPATED (4): + No known exploitation activity, but has a + high potential for exploitation. + NO_KNOWN (5): + No known exploitation activity. + """ + EXPLOITATION_ACTIVITY_UNSPECIFIED = 0 + WIDE = 1 + CONFIRMED = 2 + AVAILABLE = 3 + ANTICIPATED = 4 + NO_KNOWN = 5 + + id: str = proto.Field( + proto.STRING, + number=1, + ) + references: MutableSequence["Reference"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="Reference", + ) + cvssv3: "Cvssv3" = proto.Field( + proto.MESSAGE, + number=3, + message="Cvssv3", + ) + upstream_fix_available: bool = proto.Field( + proto.BOOL, + number=4, + ) + impact: RiskRating = proto.Field( + proto.ENUM, + number=5, + enum=RiskRating, + ) + exploitation_activity: ExploitationActivity = proto.Field( + proto.ENUM, + number=6, + enum=ExploitationActivity, + ) + observed_in_the_wild: bool = proto.Field( + proto.BOOL, + number=7, + ) + zero_day: bool = proto.Field( + proto.BOOL, + number=8, + ) + + +class Reference(proto.Message): + r"""Additional Links + + Attributes: + source (str): + Source of the reference e.g. NVD + uri (str): + Uri for the mentioned source e.g. + https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-34527. + """ + + source: str = proto.Field( + proto.STRING, + number=1, + ) + uri: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Cvssv3(proto.Message): + r"""Common Vulnerability Scoring System version 3. + + Attributes: + base_score (float): + The base score is a function of the base + metric scores. + attack_vector (google.cloud.securitycenter_v2.types.Cvssv3.AttackVector): + Base Metrics + Represents the intrinsic characteristics of a + vulnerability that are constant over time and + across user environments. This metric reflects + the context by which vulnerability exploitation + is possible. + attack_complexity (google.cloud.securitycenter_v2.types.Cvssv3.AttackComplexity): + This metric describes the conditions beyond + the attacker's control that must exist in order + to exploit the vulnerability. + privileges_required (google.cloud.securitycenter_v2.types.Cvssv3.PrivilegesRequired): + This metric describes the level of privileges + an attacker must possess before successfully + exploiting the vulnerability. + user_interaction (google.cloud.securitycenter_v2.types.Cvssv3.UserInteraction): + This metric captures the requirement for a + human user, other than the attacker, to + participate in the successful compromise of the + vulnerable component. + scope (google.cloud.securitycenter_v2.types.Cvssv3.Scope): + The Scope metric captures whether a + vulnerability in one vulnerable component + impacts resources in components beyond its + security scope. + confidentiality_impact (google.cloud.securitycenter_v2.types.Cvssv3.Impact): + This metric measures the impact to the + confidentiality of the information resources + managed by a software component due to a + successfully exploited vulnerability. + integrity_impact (google.cloud.securitycenter_v2.types.Cvssv3.Impact): + This metric measures the impact to integrity + of a successfully exploited vulnerability. + availability_impact (google.cloud.securitycenter_v2.types.Cvssv3.Impact): + This metric measures the impact to the + availability of the impacted component resulting + from a successfully exploited vulnerability. + """ + + class AttackVector(proto.Enum): + r"""This metric reflects the context by which vulnerability + exploitation is possible. + + Values: + ATTACK_VECTOR_UNSPECIFIED (0): + Invalid value. + ATTACK_VECTOR_NETWORK (1): + The vulnerable component is bound to the + network stack and the set of possible attackers + extends beyond the other options listed below, + up to and including the entire Internet. + ATTACK_VECTOR_ADJACENT (2): + The vulnerable component is bound to the + network stack, but the attack is limited at the + protocol level to a logically adjacent topology. + ATTACK_VECTOR_LOCAL (3): + The vulnerable component is not bound to the + network stack and the attacker's path is via + read/write/execute capabilities. + ATTACK_VECTOR_PHYSICAL (4): + The attack requires the attacker to + physically touch or manipulate the vulnerable + component. + """ + ATTACK_VECTOR_UNSPECIFIED = 0 + ATTACK_VECTOR_NETWORK = 1 + ATTACK_VECTOR_ADJACENT = 2 + ATTACK_VECTOR_LOCAL = 3 + ATTACK_VECTOR_PHYSICAL = 4 + + class AttackComplexity(proto.Enum): + r"""This metric describes the conditions beyond the attacker's + control that must exist in order to exploit the vulnerability. + + Values: + ATTACK_COMPLEXITY_UNSPECIFIED (0): + Invalid value. + ATTACK_COMPLEXITY_LOW (1): + Specialized access conditions or extenuating + circumstances do not exist. An attacker can + expect repeatable success when attacking the + vulnerable component. + ATTACK_COMPLEXITY_HIGH (2): + A successful attack depends on conditions + beyond the attacker's control. That is, a + successful attack cannot be accomplished at + will, but requires the attacker to invest in + some measurable amount of effort in preparation + or execution against the vulnerable component + before a successful attack can be expected. + """ + ATTACK_COMPLEXITY_UNSPECIFIED = 0 + ATTACK_COMPLEXITY_LOW = 1 + ATTACK_COMPLEXITY_HIGH = 2 + + class PrivilegesRequired(proto.Enum): + r"""This metric describes the level of privileges an attacker + must possess before successfully exploiting the vulnerability. + + Values: + PRIVILEGES_REQUIRED_UNSPECIFIED (0): + Invalid value. + PRIVILEGES_REQUIRED_NONE (1): + The attacker is unauthorized prior to attack, + and therefore does not require any access to + settings or files of the vulnerable system to + carry out an attack. + PRIVILEGES_REQUIRED_LOW (2): + The attacker requires privileges that provide + basic user capabilities that could normally + affect only settings and files owned by a user. + Alternatively, an attacker with Low privileges + has the ability to access only non-sensitive + resources. + PRIVILEGES_REQUIRED_HIGH (3): + The attacker requires privileges that provide + significant (e.g., administrative) control over + the vulnerable component allowing access to + component-wide settings and files. + """ + PRIVILEGES_REQUIRED_UNSPECIFIED = 0 + PRIVILEGES_REQUIRED_NONE = 1 + PRIVILEGES_REQUIRED_LOW = 2 + PRIVILEGES_REQUIRED_HIGH = 3 + + class UserInteraction(proto.Enum): + r"""This metric captures the requirement for a human user, other + than the attacker, to participate in the successful compromise + of the vulnerable component. + + Values: + USER_INTERACTION_UNSPECIFIED (0): + Invalid value. + USER_INTERACTION_NONE (1): + The vulnerable system can be exploited + without interaction from any user. + USER_INTERACTION_REQUIRED (2): + Successful exploitation of this vulnerability + requires a user to take some action before the + vulnerability can be exploited. + """ + USER_INTERACTION_UNSPECIFIED = 0 + USER_INTERACTION_NONE = 1 + USER_INTERACTION_REQUIRED = 2 + + class Scope(proto.Enum): + r"""The Scope metric captures whether a vulnerability in one + vulnerable component impacts resources in components beyond its + security scope. + + Values: + SCOPE_UNSPECIFIED (0): + Invalid value. + SCOPE_UNCHANGED (1): + An exploited vulnerability can only affect + resources managed by the same security + authority. + SCOPE_CHANGED (2): + An exploited vulnerability can affect + resources beyond the security scope managed by + the security authority of the vulnerable + component. + """ + SCOPE_UNSPECIFIED = 0 + SCOPE_UNCHANGED = 1 + SCOPE_CHANGED = 2 + + class Impact(proto.Enum): + r"""The Impact metrics capture the effects of a successfully + exploited vulnerability on the component that suffers the worst + outcome that is most directly and predictably associated with + the attack. + + Values: + IMPACT_UNSPECIFIED (0): + Invalid value. + IMPACT_HIGH (1): + High impact. + IMPACT_LOW (2): + Low impact. + IMPACT_NONE (3): + No impact. + """ + IMPACT_UNSPECIFIED = 0 + IMPACT_HIGH = 1 + IMPACT_LOW = 2 + IMPACT_NONE = 3 + + base_score: float = proto.Field( + proto.DOUBLE, + number=1, + ) + attack_vector: AttackVector = proto.Field( + proto.ENUM, + number=2, + enum=AttackVector, + ) + attack_complexity: AttackComplexity = proto.Field( + proto.ENUM, + number=3, + enum=AttackComplexity, + ) + privileges_required: PrivilegesRequired = proto.Field( + proto.ENUM, + number=4, + enum=PrivilegesRequired, + ) + user_interaction: UserInteraction = proto.Field( + proto.ENUM, + number=5, + enum=UserInteraction, + ) + scope: Scope = proto.Field( + proto.ENUM, + number=6, + enum=Scope, + ) + confidentiality_impact: Impact = proto.Field( + proto.ENUM, + number=7, + enum=Impact, + ) + integrity_impact: Impact = proto.Field( + proto.ENUM, + number=8, + enum=Impact, + ) + availability_impact: Impact = proto.Field( + proto.ENUM, + number=9, + enum=Impact, + ) + + +class Package(proto.Message): + r"""Package is a generic definition of a package. + + Attributes: + package_name (str): + The name of the package where the + vulnerability was detected. + cpe_uri (str): + The CPE URI where the vulnerability was + detected. + package_type (str): + Type of package, for example, os, maven, or + go. + package_version (str): + The version of the package. + """ + + package_name: str = proto.Field( + proto.STRING, + number=1, + ) + cpe_uri: str = proto.Field( + proto.STRING, + number=2, + ) + package_type: str = proto.Field( + proto.STRING, + number=3, + ) + package_version: str = proto.Field( + proto.STRING, + number=4, + ) + + +class SecurityBulletin(proto.Message): + r"""SecurityBulletin are notifications of vulnerabilities of + Google products. + + Attributes: + bulletin_id (str): + ID of the bulletin corresponding to the + vulnerability. + submission_time (google.protobuf.timestamp_pb2.Timestamp): + Submission time of this Security Bulletin. + suggested_upgrade_version (str): + This represents a version that the cluster + receiving this notification should be upgraded + to, based on its current version. For example, + 1.15.0 + """ + + bulletin_id: str = proto.Field( + proto.STRING, + number=1, + ) + submission_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + suggested_upgrade_version: str = proto.Field( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_batch_create_resource_value_configs_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_batch_create_resource_value_configs_async.py new file mode 100644 index 000000000000..09f81fcd1556 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_batch_create_resource_value_configs_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreateResourceValueConfigs +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_BatchCreateResourceValueConfigs_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_batch_create_resource_value_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + requests = securitycenter_v2.CreateResourceValueConfigRequest() + requests.parent = "parent_value" + requests.resource_value_config.tag_values = ['tag_values_value1', 'tag_values_value2'] + + request = securitycenter_v2.BatchCreateResourceValueConfigsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = await client.batch_create_resource_value_configs(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_BatchCreateResourceValueConfigs_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_batch_create_resource_value_configs_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_batch_create_resource_value_configs_sync.py new file mode 100644 index 000000000000..c824e5cc44fc --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_batch_create_resource_value_configs_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreateResourceValueConfigs +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_BatchCreateResourceValueConfigs_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_batch_create_resource_value_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + requests = securitycenter_v2.CreateResourceValueConfigRequest() + requests.parent = "parent_value" + requests.resource_value_config.tag_values = ['tag_values_value1', 'tag_values_value2'] + + request = securitycenter_v2.BatchCreateResourceValueConfigsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_resource_value_configs(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_BatchCreateResourceValueConfigs_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_bulk_mute_findings_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_bulk_mute_findings_async.py new file mode 100644 index 000000000000..182589def6dd --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_bulk_mute_findings_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BulkMuteFindings +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_BulkMuteFindings_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_bulk_mute_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.BulkMuteFindingsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.bulk_mute_findings(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_BulkMuteFindings_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_bulk_mute_findings_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_bulk_mute_findings_sync.py new file mode 100644 index 000000000000..548a8582ba63 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_bulk_mute_findings_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BulkMuteFindings +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_BulkMuteFindings_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_bulk_mute_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.BulkMuteFindingsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.bulk_mute_findings(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_BulkMuteFindings_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_big_query_export_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_big_query_export_async.py new file mode 100644 index 000000000000..fd21231017d3 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_big_query_export_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateBigQueryExport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_CreateBigQueryExport_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_create_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateBigQueryExportRequest( + parent="parent_value", + big_query_export_id="big_query_export_id_value", + ) + + # Make the request + response = await client.create_big_query_export(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_CreateBigQueryExport_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_big_query_export_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_big_query_export_sync.py new file mode 100644 index 000000000000..30002476f096 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_big_query_export_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateBigQueryExport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_CreateBigQueryExport_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_create_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateBigQueryExportRequest( + parent="parent_value", + big_query_export_id="big_query_export_id_value", + ) + + # Make the request + response = client.create_big_query_export(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_CreateBigQueryExport_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_finding_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_finding_async.py new file mode 100644 index 000000000000..437f9ca84dee --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_finding_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateFinding +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_CreateFinding_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_create_finding(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateFindingRequest( + parent="parent_value", + finding_id="finding_id_value", + ) + + # Make the request + response = await client.create_finding(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_CreateFinding_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_finding_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_finding_sync.py new file mode 100644 index 000000000000..175029b80519 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_finding_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateFinding +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_CreateFinding_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_create_finding(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateFindingRequest( + parent="parent_value", + finding_id="finding_id_value", + ) + + # Make the request + response = client.create_finding(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_CreateFinding_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_mute_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_mute_config_async.py new file mode 100644 index 000000000000..274733b9f6cd --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_mute_config_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateMuteConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_CreateMuteConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_create_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + mute_config = securitycenter_v2.MuteConfig() + mute_config.filter = "filter_value" + mute_config.type_ = "STATIC" + + request = securitycenter_v2.CreateMuteConfigRequest( + parent="parent_value", + mute_config=mute_config, + mute_config_id="mute_config_id_value", + ) + + # Make the request + response = await client.create_mute_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_CreateMuteConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_mute_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_mute_config_sync.py new file mode 100644 index 000000000000..bb135f66db0e --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_mute_config_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateMuteConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_CreateMuteConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_create_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + mute_config = securitycenter_v2.MuteConfig() + mute_config.filter = "filter_value" + mute_config.type_ = "STATIC" + + request = securitycenter_v2.CreateMuteConfigRequest( + parent="parent_value", + mute_config=mute_config, + mute_config_id="mute_config_id_value", + ) + + # Make the request + response = client.create_mute_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_CreateMuteConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_notification_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_notification_config_async.py new file mode 100644 index 000000000000..20e2140445ba --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_notification_config_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateNotificationConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_CreateNotificationConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_create_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateNotificationConfigRequest( + parent="parent_value", + config_id="config_id_value", + ) + + # Make the request + response = await client.create_notification_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_CreateNotificationConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_notification_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_notification_config_sync.py new file mode 100644 index 000000000000..1d72841f51ef --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_notification_config_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateNotificationConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_CreateNotificationConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_create_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateNotificationConfigRequest( + parent="parent_value", + config_id="config_id_value", + ) + + # Make the request + response = client.create_notification_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_CreateNotificationConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_source_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_source_async.py new file mode 100644 index 000000000000..0760b9e60b29 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_source_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateSource +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_CreateSource_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_create_source(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateSourceRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_source(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_CreateSource_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_source_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_source_sync.py new file mode 100644 index 000000000000..b435396de991 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_create_source_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateSource +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_CreateSource_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_create_source(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.CreateSourceRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_source(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_CreateSource_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_big_query_export_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_big_query_export_async.py new file mode 100644 index 000000000000..09514a6c586b --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_big_query_export_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteBigQueryExport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_DeleteBigQueryExport_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_delete_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteBigQueryExportRequest( + name="name_value", + ) + + # Make the request + await client.delete_big_query_export(request=request) + + +# [END securitycenter_v2_generated_SecurityCenter_DeleteBigQueryExport_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_big_query_export_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_big_query_export_sync.py new file mode 100644 index 000000000000..b9c79943893a --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_big_query_export_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteBigQueryExport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_DeleteBigQueryExport_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_delete_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteBigQueryExportRequest( + name="name_value", + ) + + # Make the request + client.delete_big_query_export(request=request) + + +# [END securitycenter_v2_generated_SecurityCenter_DeleteBigQueryExport_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_mute_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_mute_config_async.py new file mode 100644 index 000000000000..f0f7a717f4d7 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_mute_config_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteMuteConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_DeleteMuteConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_delete_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteMuteConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_mute_config(request=request) + + +# [END securitycenter_v2_generated_SecurityCenter_DeleteMuteConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_mute_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_mute_config_sync.py new file mode 100644 index 000000000000..ca000be4b95a --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_mute_config_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteMuteConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_DeleteMuteConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_delete_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteMuteConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_mute_config(request=request) + + +# [END securitycenter_v2_generated_SecurityCenter_DeleteMuteConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_notification_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_notification_config_async.py new file mode 100644 index 000000000000..d752dc809b16 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_notification_config_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteNotificationConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_DeleteNotificationConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_delete_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteNotificationConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_notification_config(request=request) + + +# [END securitycenter_v2_generated_SecurityCenter_DeleteNotificationConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_notification_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_notification_config_sync.py new file mode 100644 index 000000000000..9b650404c527 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_notification_config_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteNotificationConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_DeleteNotificationConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_delete_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteNotificationConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_notification_config(request=request) + + +# [END securitycenter_v2_generated_SecurityCenter_DeleteNotificationConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_resource_value_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_resource_value_config_async.py new file mode 100644 index 000000000000..5063c4556cd2 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_resource_value_config_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteResourceValueConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_DeleteResourceValueConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_delete_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteResourceValueConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_resource_value_config(request=request) + + +# [END securitycenter_v2_generated_SecurityCenter_DeleteResourceValueConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_resource_value_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_resource_value_config_sync.py new file mode 100644 index 000000000000..eb65e65e197a --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_delete_resource_value_config_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteResourceValueConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_DeleteResourceValueConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_delete_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.DeleteResourceValueConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_resource_value_config(request=request) + + +# [END securitycenter_v2_generated_SecurityCenter_DeleteResourceValueConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_big_query_export_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_big_query_export_async.py new file mode 100644 index 000000000000..1e2892d7847e --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_big_query_export_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetBigQueryExport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetBigQueryExport_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_get_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetBigQueryExportRequest( + name="name_value", + ) + + # Make the request + response = await client.get_big_query_export(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetBigQueryExport_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_big_query_export_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_big_query_export_sync.py new file mode 100644 index 000000000000..b3b4388e1b5e --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_big_query_export_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetBigQueryExport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetBigQueryExport_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_get_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetBigQueryExportRequest( + name="name_value", + ) + + # Make the request + response = client.get_big_query_export(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetBigQueryExport_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_iam_policy_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_iam_policy_async.py new file mode 100644 index 000000000000..e4328bd28868 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_iam_policy_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetIamPolicy +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetIamPolicy_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 +from google.iam.v1 import iam_policy_pb2 # type: ignore + + +async def sample_get_iam_policy(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = iam_policy_pb2.GetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = await client.get_iam_policy(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetIamPolicy_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_iam_policy_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_iam_policy_sync.py new file mode 100644 index 000000000000..63c5251ec9ad --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_iam_policy_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetIamPolicy +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetIamPolicy_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 +from google.iam.v1 import iam_policy_pb2 # type: ignore + + +def sample_get_iam_policy(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = iam_policy_pb2.GetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = client.get_iam_policy(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetIamPolicy_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_mute_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_mute_config_async.py new file mode 100644 index 000000000000..12d09197fc9d --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_mute_config_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetMuteConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetMuteConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_get_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetMuteConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_mute_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetMuteConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_mute_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_mute_config_sync.py new file mode 100644 index 000000000000..e1831aa59d7c --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_mute_config_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetMuteConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetMuteConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_get_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetMuteConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_mute_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetMuteConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_notification_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_notification_config_async.py new file mode 100644 index 000000000000..ae049e4c68c3 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_notification_config_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetNotificationConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetNotificationConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_get_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetNotificationConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_notification_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetNotificationConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_notification_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_notification_config_sync.py new file mode 100644 index 000000000000..d40ad524a70d --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_notification_config_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetNotificationConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetNotificationConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_get_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetNotificationConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_notification_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetNotificationConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_resource_value_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_resource_value_config_async.py new file mode 100644 index 000000000000..935654ee8a31 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_resource_value_config_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetResourceValueConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetResourceValueConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_get_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetResourceValueConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_resource_value_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetResourceValueConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_resource_value_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_resource_value_config_sync.py new file mode 100644 index 000000000000..a6934cd25773 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_resource_value_config_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetResourceValueConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetResourceValueConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_get_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetResourceValueConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_resource_value_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetResourceValueConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_simulation_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_simulation_async.py new file mode 100644 index 000000000000..d684db849aeb --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_simulation_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetSimulation +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetSimulation_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_get_simulation(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetSimulationRequest( + name="name_value", + ) + + # Make the request + response = await client.get_simulation(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetSimulation_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_simulation_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_simulation_sync.py new file mode 100644 index 000000000000..d018f7f13666 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_simulation_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetSimulation +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetSimulation_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_get_simulation(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetSimulationRequest( + name="name_value", + ) + + # Make the request + response = client.get_simulation(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetSimulation_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_source_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_source_async.py new file mode 100644 index 000000000000..19aa30222c97 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_source_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetSource +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetSource_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_get_source(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetSourceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_source(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetSource_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_source_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_source_sync.py new file mode 100644 index 000000000000..c4dcb283be53 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_source_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetSource +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetSource_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_get_source(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetSourceRequest( + name="name_value", + ) + + # Make the request + response = client.get_source(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetSource_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_valued_resource_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_valued_resource_async.py new file mode 100644 index 000000000000..6d72482fad60 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_valued_resource_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetValuedResource +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetValuedResource_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_get_valued_resource(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetValuedResourceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_valued_resource(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetValuedResource_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_valued_resource_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_valued_resource_sync.py new file mode 100644 index 000000000000..28badb6a1218 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_get_valued_resource_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetValuedResource +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GetValuedResource_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_get_valued_resource(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GetValuedResourceRequest( + name="name_value", + ) + + # Make the request + response = client.get_valued_resource(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GetValuedResource_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_group_findings_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_group_findings_async.py new file mode 100644 index 000000000000..35741f769568 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_group_findings_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GroupFindings +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GroupFindings_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_group_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.GroupFindingsRequest( + parent="parent_value", + group_by="group_by_value", + ) + + # Make the request + page_result = client.group_findings(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GroupFindings_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_group_findings_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_group_findings_sync.py new file mode 100644 index 000000000000..a9968aade568 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_group_findings_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GroupFindings +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_GroupFindings_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_group_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.GroupFindingsRequest( + parent="parent_value", + group_by="group_by_value", + ) + + # Make the request + page_result = client.group_findings(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_GroupFindings_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_attack_paths_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_attack_paths_async.py new file mode 100644 index 000000000000..0de8471f9b74 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_attack_paths_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListAttackPaths +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListAttackPaths_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_list_attack_paths(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListAttackPathsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_attack_paths(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListAttackPaths_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_attack_paths_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_attack_paths_sync.py new file mode 100644 index 000000000000..27cd22123449 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_attack_paths_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListAttackPaths +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListAttackPaths_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_list_attack_paths(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListAttackPathsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_attack_paths(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListAttackPaths_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_big_query_exports_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_big_query_exports_async.py new file mode 100644 index 000000000000..e47b6e0585de --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_big_query_exports_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListBigQueryExports +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListBigQueryExports_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_list_big_query_exports(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListBigQueryExportsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_big_query_exports(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListBigQueryExports_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_big_query_exports_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_big_query_exports_sync.py new file mode 100644 index 000000000000..a2ab227b5ca0 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_big_query_exports_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListBigQueryExports +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListBigQueryExports_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_list_big_query_exports(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListBigQueryExportsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_big_query_exports(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListBigQueryExports_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_findings_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_findings_async.py new file mode 100644 index 000000000000..6c288226cad1 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_findings_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListFindings +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListFindings_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_list_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListFindingsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_findings(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListFindings_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_findings_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_findings_sync.py new file mode 100644 index 000000000000..8aa84c3d1450 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_findings_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListFindings +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListFindings_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_list_findings(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListFindingsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_findings(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListFindings_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_mute_configs_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_mute_configs_async.py new file mode 100644 index 000000000000..b374f7cace05 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_mute_configs_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListMuteConfigs +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListMuteConfigs_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_list_mute_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListMuteConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_mute_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListMuteConfigs_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_mute_configs_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_mute_configs_sync.py new file mode 100644 index 000000000000..9910452c0653 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_mute_configs_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListMuteConfigs +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListMuteConfigs_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_list_mute_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListMuteConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_mute_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListMuteConfigs_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_notification_configs_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_notification_configs_async.py new file mode 100644 index 000000000000..c42f84b0e5c2 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_notification_configs_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListNotificationConfigs +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListNotificationConfigs_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_list_notification_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListNotificationConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_notification_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListNotificationConfigs_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_notification_configs_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_notification_configs_sync.py new file mode 100644 index 000000000000..749ac4c226df --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_notification_configs_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListNotificationConfigs +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListNotificationConfigs_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_list_notification_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListNotificationConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_notification_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListNotificationConfigs_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_resource_value_configs_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_resource_value_configs_async.py new file mode 100644 index 000000000000..7ea7d3cb138c --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_resource_value_configs_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListResourceValueConfigs +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListResourceValueConfigs_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_list_resource_value_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListResourceValueConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_resource_value_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListResourceValueConfigs_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_resource_value_configs_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_resource_value_configs_sync.py new file mode 100644 index 000000000000..de3aa53fcf7f --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_resource_value_configs_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListResourceValueConfigs +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListResourceValueConfigs_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_list_resource_value_configs(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListResourceValueConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_resource_value_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListResourceValueConfigs_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_sources_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_sources_async.py new file mode 100644 index 000000000000..e8e9b525586c --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_sources_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListSources +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListSources_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_list_sources(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListSourcesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_sources(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListSources_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_sources_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_sources_sync.py new file mode 100644 index 000000000000..1941d1558472 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_sources_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListSources +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListSources_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_list_sources(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListSourcesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_sources(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListSources_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_valued_resources_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_valued_resources_async.py new file mode 100644 index 000000000000..88ae351bcda8 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_valued_resources_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListValuedResources +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListValuedResources_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_list_valued_resources(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListValuedResourcesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_valued_resources(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListValuedResources_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_valued_resources_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_valued_resources_sync.py new file mode 100644 index 000000000000..35b90be4a15b --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_list_valued_resources_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListValuedResources +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_ListValuedResources_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_list_valued_resources(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.ListValuedResourcesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_valued_resources(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_ListValuedResources_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_finding_state_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_finding_state_async.py new file mode 100644 index 000000000000..f83c03070ebf --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_finding_state_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SetFindingState +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_SetFindingState_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_set_finding_state(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.SetFindingStateRequest( + name="name_value", + state="INACTIVE", + ) + + # Make the request + response = await client.set_finding_state(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_SetFindingState_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_finding_state_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_finding_state_sync.py new file mode 100644 index 000000000000..45f8a0a539a2 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_finding_state_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SetFindingState +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_SetFindingState_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_set_finding_state(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.SetFindingStateRequest( + name="name_value", + state="INACTIVE", + ) + + # Make the request + response = client.set_finding_state(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_SetFindingState_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_iam_policy_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_iam_policy_async.py new file mode 100644 index 000000000000..2c16ac80c521 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_iam_policy_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SetIamPolicy +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_SetIamPolicy_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 +from google.iam.v1 import iam_policy_pb2 # type: ignore + + +async def sample_set_iam_policy(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = iam_policy_pb2.SetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = await client.set_iam_policy(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_SetIamPolicy_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_iam_policy_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_iam_policy_sync.py new file mode 100644 index 000000000000..460629d25c3a --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_iam_policy_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SetIamPolicy +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_SetIamPolicy_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 +from google.iam.v1 import iam_policy_pb2 # type: ignore + + +def sample_set_iam_policy(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = iam_policy_pb2.SetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = client.set_iam_policy(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_SetIamPolicy_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_mute_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_mute_async.py new file mode 100644 index 000000000000..1e4c52470ed2 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_mute_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SetMute +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_SetMute_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_set_mute(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.SetMuteRequest( + name="name_value", + mute="UNDEFINED", + ) + + # Make the request + response = await client.set_mute(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_SetMute_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_mute_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_mute_sync.py new file mode 100644 index 000000000000..047c41733d0a --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_set_mute_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SetMute +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_SetMute_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_set_mute(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.SetMuteRequest( + name="name_value", + mute="UNDEFINED", + ) + + # Make the request + response = client.set_mute(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_SetMute_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_test_iam_permissions_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_test_iam_permissions_async.py new file mode 100644 index 000000000000..bd5d0532ee4d --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_test_iam_permissions_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for TestIamPermissions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_TestIamPermissions_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 +from google.iam.v1 import iam_policy_pb2 # type: ignore + + +async def sample_test_iam_permissions(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = iam_policy_pb2.TestIamPermissionsRequest( + resource="resource_value", + permissions=['permissions_value1', 'permissions_value2'], + ) + + # Make the request + response = await client.test_iam_permissions(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_TestIamPermissions_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_test_iam_permissions_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_test_iam_permissions_sync.py new file mode 100644 index 000000000000..0be3fd09b0c8 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_test_iam_permissions_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for TestIamPermissions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_TestIamPermissions_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 +from google.iam.v1 import iam_policy_pb2 # type: ignore + + +def sample_test_iam_permissions(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = iam_policy_pb2.TestIamPermissionsRequest( + resource="resource_value", + permissions=['permissions_value1', 'permissions_value2'], + ) + + # Make the request + response = client.test_iam_permissions(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_TestIamPermissions_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_big_query_export_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_big_query_export_async.py new file mode 100644 index 000000000000..b8f63f0b812a --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_big_query_export_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateBigQueryExport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateBigQueryExport_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_update_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateBigQueryExportRequest( + ) + + # Make the request + response = await client.update_big_query_export(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateBigQueryExport_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_big_query_export_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_big_query_export_sync.py new file mode 100644 index 000000000000..0c101eac0e1b --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_big_query_export_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateBigQueryExport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateBigQueryExport_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_update_big_query_export(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateBigQueryExportRequest( + ) + + # Make the request + response = client.update_big_query_export(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateBigQueryExport_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_external_system_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_external_system_async.py new file mode 100644 index 000000000000..2c89ce1d1032 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_external_system_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateExternalSystem +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateExternalSystem_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_update_external_system(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateExternalSystemRequest( + ) + + # Make the request + response = await client.update_external_system(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateExternalSystem_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_external_system_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_external_system_sync.py new file mode 100644 index 000000000000..a1f26954c850 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_external_system_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateExternalSystem +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateExternalSystem_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_update_external_system(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateExternalSystemRequest( + ) + + # Make the request + response = client.update_external_system(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateExternalSystem_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_finding_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_finding_async.py new file mode 100644 index 000000000000..fb650c701471 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_finding_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateFinding +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateFinding_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_update_finding(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateFindingRequest( + ) + + # Make the request + response = await client.update_finding(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateFinding_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_finding_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_finding_sync.py new file mode 100644 index 000000000000..836dcf9c07a9 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_finding_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateFinding +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateFinding_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_update_finding(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateFindingRequest( + ) + + # Make the request + response = client.update_finding(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateFinding_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_mute_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_mute_config_async.py new file mode 100644 index 000000000000..eaad23353dd6 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_mute_config_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateMuteConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateMuteConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_update_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + mute_config = securitycenter_v2.MuteConfig() + mute_config.filter = "filter_value" + mute_config.type_ = "STATIC" + + request = securitycenter_v2.UpdateMuteConfigRequest( + mute_config=mute_config, + ) + + # Make the request + response = await client.update_mute_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateMuteConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_mute_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_mute_config_sync.py new file mode 100644 index 000000000000..b7caba9cce40 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_mute_config_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateMuteConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateMuteConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_update_mute_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + mute_config = securitycenter_v2.MuteConfig() + mute_config.filter = "filter_value" + mute_config.type_ = "STATIC" + + request = securitycenter_v2.UpdateMuteConfigRequest( + mute_config=mute_config, + ) + + # Make the request + response = client.update_mute_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateMuteConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_notification_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_notification_config_async.py new file mode 100644 index 000000000000..168abc290e11 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_notification_config_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateNotificationConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateNotificationConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_update_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateNotificationConfigRequest( + ) + + # Make the request + response = await client.update_notification_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateNotificationConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_notification_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_notification_config_sync.py new file mode 100644 index 000000000000..3643aaf5c813 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_notification_config_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateNotificationConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateNotificationConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_update_notification_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateNotificationConfigRequest( + ) + + # Make the request + response = client.update_notification_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateNotificationConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_resource_value_config_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_resource_value_config_async.py new file mode 100644 index 000000000000..e8badabb634c --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_resource_value_config_async.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateResourceValueConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateResourceValueConfig_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_update_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + resource_value_config = securitycenter_v2.ResourceValueConfig() + resource_value_config.tag_values = ['tag_values_value1', 'tag_values_value2'] + + request = securitycenter_v2.UpdateResourceValueConfigRequest( + resource_value_config=resource_value_config, + ) + + # Make the request + response = await client.update_resource_value_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateResourceValueConfig_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_resource_value_config_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_resource_value_config_sync.py new file mode 100644 index 000000000000..748d9b291a25 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_resource_value_config_sync.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateResourceValueConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateResourceValueConfig_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_update_resource_value_config(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + resource_value_config = securitycenter_v2.ResourceValueConfig() + resource_value_config.tag_values = ['tag_values_value1', 'tag_values_value2'] + + request = securitycenter_v2.UpdateResourceValueConfigRequest( + resource_value_config=resource_value_config, + ) + + # Make the request + response = client.update_resource_value_config(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateResourceValueConfig_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_security_marks_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_security_marks_async.py new file mode 100644 index 000000000000..44663258c63d --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_security_marks_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSecurityMarks +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateSecurityMarks_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_update_security_marks(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateSecurityMarksRequest( + ) + + # Make the request + response = await client.update_security_marks(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateSecurityMarks_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_security_marks_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_security_marks_sync.py new file mode 100644 index 000000000000..6f30a6a41442 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_security_marks_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSecurityMarks +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateSecurityMarks_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_update_security_marks(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateSecurityMarksRequest( + ) + + # Make the request + response = client.update_security_marks(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateSecurityMarks_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_source_async.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_source_async.py new file mode 100644 index 000000000000..200906386274 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_source_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSource +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateSource_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +async def sample_update_source(): + # Create a client + client = securitycenter_v2.SecurityCenterAsyncClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateSourceRequest( + ) + + # Make the request + response = await client.update_source(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateSource_async] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_source_sync.py b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_source_sync.py new file mode 100644 index 000000000000..c1299083aaf6 --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/securitycenter_v2_generated_security_center_update_source_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSource +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-securitycenter + + +# [START securitycenter_v2_generated_SecurityCenter_UpdateSource_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import securitycenter_v2 + + +def sample_update_source(): + # Create a client + client = securitycenter_v2.SecurityCenterClient() + + # Initialize request argument(s) + request = securitycenter_v2.UpdateSourceRequest( + ) + + # Make the request + response = client.update_source(request=request) + + # Handle the response + print(response) + +# [END securitycenter_v2_generated_SecurityCenter_UpdateSource_sync] diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1.json b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1.json index ec515b030621..278ec40bb216 100644 --- a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1.json +++ b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-securitycenter", - "version": "1.27.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1beta1.json b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1beta1.json index 9d94361df18e..a4c1295eaf99 100644 --- a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1beta1.json +++ b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-securitycenter", - "version": "1.27.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1p1beta1.json b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1p1beta1.json index 490db3155719..774592ce11f7 100644 --- a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1p1beta1.json +++ b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1p1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-securitycenter", - "version": "1.27.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v2.json b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v2.json new file mode 100644 index 000000000000..6672c033126b --- /dev/null +++ b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v2.json @@ -0,0 +1,6607 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.securitycenter.v2", + "version": "v2" + } + ], + "language": "PYTHON", + "name": "google-cloud-securitycenter", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.batch_create_resource_value_configs", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.BatchCreateResourceValueConfigs", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "BatchCreateResourceValueConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.BatchCreateResourceValueConfigsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.securitycenter_v2.types.CreateResourceValueConfigRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.BatchCreateResourceValueConfigsResponse", + "shortName": "batch_create_resource_value_configs" + }, + "description": "Sample for BatchCreateResourceValueConfigs", + "file": "securitycenter_v2_generated_security_center_batch_create_resource_value_configs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_BatchCreateResourceValueConfigs_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_batch_create_resource_value_configs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.batch_create_resource_value_configs", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.BatchCreateResourceValueConfigs", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "BatchCreateResourceValueConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.BatchCreateResourceValueConfigsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.securitycenter_v2.types.CreateResourceValueConfigRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.BatchCreateResourceValueConfigsResponse", + "shortName": "batch_create_resource_value_configs" + }, + "description": "Sample for BatchCreateResourceValueConfigs", + "file": "securitycenter_v2_generated_security_center_batch_create_resource_value_configs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_BatchCreateResourceValueConfigs_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_batch_create_resource_value_configs_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.bulk_mute_findings", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.BulkMuteFindings", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "BulkMuteFindings" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.BulkMuteFindingsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "bulk_mute_findings" + }, + "description": "Sample for BulkMuteFindings", + "file": "securitycenter_v2_generated_security_center_bulk_mute_findings_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_BulkMuteFindings_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_bulk_mute_findings_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.bulk_mute_findings", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.BulkMuteFindings", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "BulkMuteFindings" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.BulkMuteFindingsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "bulk_mute_findings" + }, + "description": "Sample for BulkMuteFindings", + "file": "securitycenter_v2_generated_security_center_bulk_mute_findings_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_BulkMuteFindings_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_bulk_mute_findings_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.create_big_query_export", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.CreateBigQueryExport", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "CreateBigQueryExport" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.CreateBigQueryExportRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "big_query_export", + "type": "google.cloud.securitycenter_v2.types.BigQueryExport" + }, + { + "name": "big_query_export_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.BigQueryExport", + "shortName": "create_big_query_export" + }, + "description": "Sample for CreateBigQueryExport", + "file": "securitycenter_v2_generated_security_center_create_big_query_export_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_CreateBigQueryExport_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_create_big_query_export_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.create_big_query_export", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.CreateBigQueryExport", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "CreateBigQueryExport" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.CreateBigQueryExportRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "big_query_export", + "type": "google.cloud.securitycenter_v2.types.BigQueryExport" + }, + { + "name": "big_query_export_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.BigQueryExport", + "shortName": "create_big_query_export" + }, + "description": "Sample for CreateBigQueryExport", + "file": "securitycenter_v2_generated_security_center_create_big_query_export_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_CreateBigQueryExport_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_create_big_query_export_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.create_finding", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.CreateFinding", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "CreateFinding" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.CreateFindingRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "finding", + "type": "google.cloud.securitycenter_v2.types.Finding" + }, + { + "name": "finding_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Finding", + "shortName": "create_finding" + }, + "description": "Sample for CreateFinding", + "file": "securitycenter_v2_generated_security_center_create_finding_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_CreateFinding_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_create_finding_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.create_finding", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.CreateFinding", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "CreateFinding" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.CreateFindingRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "finding", + "type": "google.cloud.securitycenter_v2.types.Finding" + }, + { + "name": "finding_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Finding", + "shortName": "create_finding" + }, + "description": "Sample for CreateFinding", + "file": "securitycenter_v2_generated_security_center_create_finding_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_CreateFinding_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_create_finding_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.create_mute_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.CreateMuteConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "CreateMuteConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.CreateMuteConfigRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "mute_config", + "type": "google.cloud.securitycenter_v2.types.MuteConfig" + }, + { + "name": "mute_config_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.MuteConfig", + "shortName": "create_mute_config" + }, + "description": "Sample for CreateMuteConfig", + "file": "securitycenter_v2_generated_security_center_create_mute_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_CreateMuteConfig_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_create_mute_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.create_mute_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.CreateMuteConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "CreateMuteConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.CreateMuteConfigRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "mute_config", + "type": "google.cloud.securitycenter_v2.types.MuteConfig" + }, + { + "name": "mute_config_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.MuteConfig", + "shortName": "create_mute_config" + }, + "description": "Sample for CreateMuteConfig", + "file": "securitycenter_v2_generated_security_center_create_mute_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_CreateMuteConfig_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_create_mute_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.create_notification_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.CreateNotificationConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "CreateNotificationConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.CreateNotificationConfigRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "notification_config", + "type": "google.cloud.securitycenter_v2.types.NotificationConfig" + }, + { + "name": "config_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.NotificationConfig", + "shortName": "create_notification_config" + }, + "description": "Sample for CreateNotificationConfig", + "file": "securitycenter_v2_generated_security_center_create_notification_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_CreateNotificationConfig_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_create_notification_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.create_notification_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.CreateNotificationConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "CreateNotificationConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.CreateNotificationConfigRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "notification_config", + "type": "google.cloud.securitycenter_v2.types.NotificationConfig" + }, + { + "name": "config_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.NotificationConfig", + "shortName": "create_notification_config" + }, + "description": "Sample for CreateNotificationConfig", + "file": "securitycenter_v2_generated_security_center_create_notification_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_CreateNotificationConfig_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_create_notification_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.create_source", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.CreateSource", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "CreateSource" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.CreateSourceRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "source", + "type": "google.cloud.securitycenter_v2.types.Source" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Source", + "shortName": "create_source" + }, + "description": "Sample for CreateSource", + "file": "securitycenter_v2_generated_security_center_create_source_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_CreateSource_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_create_source_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.create_source", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.CreateSource", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "CreateSource" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.CreateSourceRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "source", + "type": "google.cloud.securitycenter_v2.types.Source" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Source", + "shortName": "create_source" + }, + "description": "Sample for CreateSource", + "file": "securitycenter_v2_generated_security_center_create_source_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_CreateSource_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_create_source_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.delete_big_query_export", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.DeleteBigQueryExport", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "DeleteBigQueryExport" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.DeleteBigQueryExportRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_big_query_export" + }, + "description": "Sample for DeleteBigQueryExport", + "file": "securitycenter_v2_generated_security_center_delete_big_query_export_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_DeleteBigQueryExport_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_delete_big_query_export_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.delete_big_query_export", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.DeleteBigQueryExport", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "DeleteBigQueryExport" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.DeleteBigQueryExportRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_big_query_export" + }, + "description": "Sample for DeleteBigQueryExport", + "file": "securitycenter_v2_generated_security_center_delete_big_query_export_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_DeleteBigQueryExport_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_delete_big_query_export_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.delete_mute_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.DeleteMuteConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "DeleteMuteConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.DeleteMuteConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_mute_config" + }, + "description": "Sample for DeleteMuteConfig", + "file": "securitycenter_v2_generated_security_center_delete_mute_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_DeleteMuteConfig_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_delete_mute_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.delete_mute_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.DeleteMuteConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "DeleteMuteConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.DeleteMuteConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_mute_config" + }, + "description": "Sample for DeleteMuteConfig", + "file": "securitycenter_v2_generated_security_center_delete_mute_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_DeleteMuteConfig_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_delete_mute_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.delete_notification_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.DeleteNotificationConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "DeleteNotificationConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.DeleteNotificationConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_notification_config" + }, + "description": "Sample for DeleteNotificationConfig", + "file": "securitycenter_v2_generated_security_center_delete_notification_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_DeleteNotificationConfig_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_delete_notification_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.delete_notification_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.DeleteNotificationConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "DeleteNotificationConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.DeleteNotificationConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_notification_config" + }, + "description": "Sample for DeleteNotificationConfig", + "file": "securitycenter_v2_generated_security_center_delete_notification_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_DeleteNotificationConfig_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_delete_notification_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.delete_resource_value_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.DeleteResourceValueConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "DeleteResourceValueConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.DeleteResourceValueConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_resource_value_config" + }, + "description": "Sample for DeleteResourceValueConfig", + "file": "securitycenter_v2_generated_security_center_delete_resource_value_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_DeleteResourceValueConfig_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_delete_resource_value_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.delete_resource_value_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.DeleteResourceValueConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "DeleteResourceValueConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.DeleteResourceValueConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_resource_value_config" + }, + "description": "Sample for DeleteResourceValueConfig", + "file": "securitycenter_v2_generated_security_center_delete_resource_value_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_DeleteResourceValueConfig_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_delete_resource_value_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.get_big_query_export", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetBigQueryExport", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetBigQueryExport" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetBigQueryExportRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.BigQueryExport", + "shortName": "get_big_query_export" + }, + "description": "Sample for GetBigQueryExport", + "file": "securitycenter_v2_generated_security_center_get_big_query_export_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetBigQueryExport_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_big_query_export_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.get_big_query_export", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetBigQueryExport", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetBigQueryExport" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetBigQueryExportRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.BigQueryExport", + "shortName": "get_big_query_export" + }, + "description": "Sample for GetBigQueryExport", + "file": "securitycenter_v2_generated_security_center_get_big_query_export_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetBigQueryExport_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_big_query_export_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.get_iam_policy", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetIamPolicy", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetIamPolicy" + }, + "parameters": [ + { + "name": "request", + "type": "google.iam.v1.iam_policy_pb2.GetIamPolicyRequest" + }, + { + "name": "resource", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.iam.v1.policy_pb2.Policy", + "shortName": "get_iam_policy" + }, + "description": "Sample for GetIamPolicy", + "file": "securitycenter_v2_generated_security_center_get_iam_policy_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetIamPolicy_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 41, + "start": 39, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 42, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_iam_policy_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.get_iam_policy", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetIamPolicy", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetIamPolicy" + }, + "parameters": [ + { + "name": "request", + "type": "google.iam.v1.iam_policy_pb2.GetIamPolicyRequest" + }, + { + "name": "resource", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.iam.v1.policy_pb2.Policy", + "shortName": "get_iam_policy" + }, + "description": "Sample for GetIamPolicy", + "file": "securitycenter_v2_generated_security_center_get_iam_policy_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetIamPolicy_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 41, + "start": 39, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 42, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_iam_policy_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.get_mute_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetMuteConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetMuteConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetMuteConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.MuteConfig", + "shortName": "get_mute_config" + }, + "description": "Sample for GetMuteConfig", + "file": "securitycenter_v2_generated_security_center_get_mute_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetMuteConfig_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_mute_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.get_mute_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetMuteConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetMuteConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetMuteConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.MuteConfig", + "shortName": "get_mute_config" + }, + "description": "Sample for GetMuteConfig", + "file": "securitycenter_v2_generated_security_center_get_mute_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetMuteConfig_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_mute_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.get_notification_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetNotificationConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetNotificationConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetNotificationConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.NotificationConfig", + "shortName": "get_notification_config" + }, + "description": "Sample for GetNotificationConfig", + "file": "securitycenter_v2_generated_security_center_get_notification_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetNotificationConfig_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_notification_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.get_notification_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetNotificationConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetNotificationConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetNotificationConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.NotificationConfig", + "shortName": "get_notification_config" + }, + "description": "Sample for GetNotificationConfig", + "file": "securitycenter_v2_generated_security_center_get_notification_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetNotificationConfig_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_notification_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.get_resource_value_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetResourceValueConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetResourceValueConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetResourceValueConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.ResourceValueConfig", + "shortName": "get_resource_value_config" + }, + "description": "Sample for GetResourceValueConfig", + "file": "securitycenter_v2_generated_security_center_get_resource_value_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetResourceValueConfig_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_resource_value_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.get_resource_value_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetResourceValueConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetResourceValueConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetResourceValueConfigRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.ResourceValueConfig", + "shortName": "get_resource_value_config" + }, + "description": "Sample for GetResourceValueConfig", + "file": "securitycenter_v2_generated_security_center_get_resource_value_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetResourceValueConfig_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_resource_value_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.get_simulation", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetSimulation", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetSimulation" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetSimulationRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Simulation", + "shortName": "get_simulation" + }, + "description": "Sample for GetSimulation", + "file": "securitycenter_v2_generated_security_center_get_simulation_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetSimulation_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_simulation_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.get_simulation", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetSimulation", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetSimulation" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetSimulationRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Simulation", + "shortName": "get_simulation" + }, + "description": "Sample for GetSimulation", + "file": "securitycenter_v2_generated_security_center_get_simulation_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetSimulation_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_simulation_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.get_source", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetSource", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetSource" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetSourceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Source", + "shortName": "get_source" + }, + "description": "Sample for GetSource", + "file": "securitycenter_v2_generated_security_center_get_source_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetSource_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_source_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.get_source", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetSource", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetSource" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetSourceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Source", + "shortName": "get_source" + }, + "description": "Sample for GetSource", + "file": "securitycenter_v2_generated_security_center_get_source_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetSource_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_source_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.get_valued_resource", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetValuedResource", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetValuedResource" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetValuedResourceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.ValuedResource", + "shortName": "get_valued_resource" + }, + "description": "Sample for GetValuedResource", + "file": "securitycenter_v2_generated_security_center_get_valued_resource_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetValuedResource_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_valued_resource_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.get_valued_resource", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GetValuedResource", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GetValuedResource" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GetValuedResourceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.ValuedResource", + "shortName": "get_valued_resource" + }, + "description": "Sample for GetValuedResource", + "file": "securitycenter_v2_generated_security_center_get_valued_resource_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GetValuedResource_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_get_valued_resource_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.group_findings", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GroupFindings", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GroupFindings" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GroupFindingsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "group_by", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.GroupFindingsAsyncPager", + "shortName": "group_findings" + }, + "description": "Sample for GroupFindings", + "file": "securitycenter_v2_generated_security_center_group_findings_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GroupFindings_async", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_group_findings_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.group_findings", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.GroupFindings", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "GroupFindings" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.GroupFindingsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "group_by", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.GroupFindingsPager", + "shortName": "group_findings" + }, + "description": "Sample for GroupFindings", + "file": "securitycenter_v2_generated_security_center_group_findings_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_GroupFindings_sync", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_group_findings_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.list_attack_paths", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListAttackPaths", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListAttackPaths" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListAttackPathsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListAttackPathsAsyncPager", + "shortName": "list_attack_paths" + }, + "description": "Sample for ListAttackPaths", + "file": "securitycenter_v2_generated_security_center_list_attack_paths_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListAttackPaths_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_attack_paths_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.list_attack_paths", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListAttackPaths", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListAttackPaths" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListAttackPathsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListAttackPathsPager", + "shortName": "list_attack_paths" + }, + "description": "Sample for ListAttackPaths", + "file": "securitycenter_v2_generated_security_center_list_attack_paths_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListAttackPaths_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_attack_paths_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.list_big_query_exports", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListBigQueryExports", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListBigQueryExports" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListBigQueryExportsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListBigQueryExportsAsyncPager", + "shortName": "list_big_query_exports" + }, + "description": "Sample for ListBigQueryExports", + "file": "securitycenter_v2_generated_security_center_list_big_query_exports_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListBigQueryExports_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_big_query_exports_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.list_big_query_exports", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListBigQueryExports", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListBigQueryExports" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListBigQueryExportsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListBigQueryExportsPager", + "shortName": "list_big_query_exports" + }, + "description": "Sample for ListBigQueryExports", + "file": "securitycenter_v2_generated_security_center_list_big_query_exports_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListBigQueryExports_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_big_query_exports_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.list_findings", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListFindings", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListFindings" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListFindingsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListFindingsAsyncPager", + "shortName": "list_findings" + }, + "description": "Sample for ListFindings", + "file": "securitycenter_v2_generated_security_center_list_findings_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListFindings_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_findings_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.list_findings", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListFindings", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListFindings" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListFindingsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListFindingsPager", + "shortName": "list_findings" + }, + "description": "Sample for ListFindings", + "file": "securitycenter_v2_generated_security_center_list_findings_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListFindings_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_findings_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.list_mute_configs", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListMuteConfigs", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListMuteConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListMuteConfigsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListMuteConfigsAsyncPager", + "shortName": "list_mute_configs" + }, + "description": "Sample for ListMuteConfigs", + "file": "securitycenter_v2_generated_security_center_list_mute_configs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListMuteConfigs_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_mute_configs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.list_mute_configs", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListMuteConfigs", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListMuteConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListMuteConfigsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListMuteConfigsPager", + "shortName": "list_mute_configs" + }, + "description": "Sample for ListMuteConfigs", + "file": "securitycenter_v2_generated_security_center_list_mute_configs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListMuteConfigs_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_mute_configs_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.list_notification_configs", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListNotificationConfigs", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListNotificationConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListNotificationConfigsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListNotificationConfigsAsyncPager", + "shortName": "list_notification_configs" + }, + "description": "Sample for ListNotificationConfigs", + "file": "securitycenter_v2_generated_security_center_list_notification_configs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListNotificationConfigs_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_notification_configs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.list_notification_configs", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListNotificationConfigs", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListNotificationConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListNotificationConfigsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListNotificationConfigsPager", + "shortName": "list_notification_configs" + }, + "description": "Sample for ListNotificationConfigs", + "file": "securitycenter_v2_generated_security_center_list_notification_configs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListNotificationConfigs_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_notification_configs_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.list_resource_value_configs", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListResourceValueConfigs", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListResourceValueConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListResourceValueConfigsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListResourceValueConfigsAsyncPager", + "shortName": "list_resource_value_configs" + }, + "description": "Sample for ListResourceValueConfigs", + "file": "securitycenter_v2_generated_security_center_list_resource_value_configs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListResourceValueConfigs_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_resource_value_configs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.list_resource_value_configs", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListResourceValueConfigs", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListResourceValueConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListResourceValueConfigsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListResourceValueConfigsPager", + "shortName": "list_resource_value_configs" + }, + "description": "Sample for ListResourceValueConfigs", + "file": "securitycenter_v2_generated_security_center_list_resource_value_configs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListResourceValueConfigs_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_resource_value_configs_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.list_sources", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListSources", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListSources" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListSourcesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListSourcesAsyncPager", + "shortName": "list_sources" + }, + "description": "Sample for ListSources", + "file": "securitycenter_v2_generated_security_center_list_sources_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListSources_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_sources_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.list_sources", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListSources", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListSources" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListSourcesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListSourcesPager", + "shortName": "list_sources" + }, + "description": "Sample for ListSources", + "file": "securitycenter_v2_generated_security_center_list_sources_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListSources_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_sources_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.list_valued_resources", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListValuedResources", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListValuedResources" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListValuedResourcesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListValuedResourcesAsyncPager", + "shortName": "list_valued_resources" + }, + "description": "Sample for ListValuedResources", + "file": "securitycenter_v2_generated_security_center_list_valued_resources_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListValuedResources_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_valued_resources_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.list_valued_resources", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.ListValuedResources", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "ListValuedResources" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.ListValuedResourcesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.services.security_center.pagers.ListValuedResourcesPager", + "shortName": "list_valued_resources" + }, + "description": "Sample for ListValuedResources", + "file": "securitycenter_v2_generated_security_center_list_valued_resources_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_ListValuedResources_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_list_valued_resources_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.set_finding_state", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.SetFindingState", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "SetFindingState" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.SetFindingStateRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "state", + "type": "google.cloud.securitycenter_v2.types.Finding.State" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Finding", + "shortName": "set_finding_state" + }, + "description": "Sample for SetFindingState", + "file": "securitycenter_v2_generated_security_center_set_finding_state_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_SetFindingState_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_set_finding_state_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.set_finding_state", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.SetFindingState", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "SetFindingState" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.SetFindingStateRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "state", + "type": "google.cloud.securitycenter_v2.types.Finding.State" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Finding", + "shortName": "set_finding_state" + }, + "description": "Sample for SetFindingState", + "file": "securitycenter_v2_generated_security_center_set_finding_state_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_SetFindingState_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_set_finding_state_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.set_iam_policy", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.SetIamPolicy", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "SetIamPolicy" + }, + "parameters": [ + { + "name": "request", + "type": "google.iam.v1.iam_policy_pb2.SetIamPolicyRequest" + }, + { + "name": "resource", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.iam.v1.policy_pb2.Policy", + "shortName": "set_iam_policy" + }, + "description": "Sample for SetIamPolicy", + "file": "securitycenter_v2_generated_security_center_set_iam_policy_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_SetIamPolicy_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 41, + "start": 39, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 42, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_set_iam_policy_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.set_iam_policy", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.SetIamPolicy", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "SetIamPolicy" + }, + "parameters": [ + { + "name": "request", + "type": "google.iam.v1.iam_policy_pb2.SetIamPolicyRequest" + }, + { + "name": "resource", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.iam.v1.policy_pb2.Policy", + "shortName": "set_iam_policy" + }, + "description": "Sample for SetIamPolicy", + "file": "securitycenter_v2_generated_security_center_set_iam_policy_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_SetIamPolicy_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 41, + "start": 39, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 42, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_set_iam_policy_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.set_mute", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.SetMute", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "SetMute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.SetMuteRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "mute", + "type": "google.cloud.securitycenter_v2.types.Finding.Mute" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Finding", + "shortName": "set_mute" + }, + "description": "Sample for SetMute", + "file": "securitycenter_v2_generated_security_center_set_mute_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_SetMute_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_set_mute_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.set_mute", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.SetMute", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "SetMute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.SetMuteRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "mute", + "type": "google.cloud.securitycenter_v2.types.Finding.Mute" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Finding", + "shortName": "set_mute" + }, + "description": "Sample for SetMute", + "file": "securitycenter_v2_generated_security_center_set_mute_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_SetMute_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_set_mute_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.test_iam_permissions", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.TestIamPermissions", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "TestIamPermissions" + }, + "parameters": [ + { + "name": "request", + "type": "google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest" + }, + { + "name": "resource", + "type": "str" + }, + { + "name": "permissions", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse", + "shortName": "test_iam_permissions" + }, + "description": "Sample for TestIamPermissions", + "file": "securitycenter_v2_generated_security_center_test_iam_permissions_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_TestIamPermissions_async", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 41, + "start": 39, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 42, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_test_iam_permissions_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.test_iam_permissions", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.TestIamPermissions", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "TestIamPermissions" + }, + "parameters": [ + { + "name": "request", + "type": "google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest" + }, + { + "name": "resource", + "type": "str" + }, + { + "name": "permissions", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse", + "shortName": "test_iam_permissions" + }, + "description": "Sample for TestIamPermissions", + "file": "securitycenter_v2_generated_security_center_test_iam_permissions_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_TestIamPermissions_sync", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 41, + "start": 39, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 42, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_test_iam_permissions_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.update_big_query_export", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateBigQueryExport", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateBigQueryExport" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateBigQueryExportRequest" + }, + { + "name": "big_query_export", + "type": "google.cloud.securitycenter_v2.types.BigQueryExport" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.BigQueryExport", + "shortName": "update_big_query_export" + }, + "description": "Sample for UpdateBigQueryExport", + "file": "securitycenter_v2_generated_security_center_update_big_query_export_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateBigQueryExport_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_big_query_export_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.update_big_query_export", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateBigQueryExport", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateBigQueryExport" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateBigQueryExportRequest" + }, + { + "name": "big_query_export", + "type": "google.cloud.securitycenter_v2.types.BigQueryExport" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.BigQueryExport", + "shortName": "update_big_query_export" + }, + "description": "Sample for UpdateBigQueryExport", + "file": "securitycenter_v2_generated_security_center_update_big_query_export_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateBigQueryExport_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_big_query_export_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.update_external_system", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateExternalSystem", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateExternalSystem" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateExternalSystemRequest" + }, + { + "name": "external_system", + "type": "google.cloud.securitycenter_v2.types.ExternalSystem" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.ExternalSystem", + "shortName": "update_external_system" + }, + "description": "Sample for UpdateExternalSystem", + "file": "securitycenter_v2_generated_security_center_update_external_system_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateExternalSystem_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_external_system_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.update_external_system", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateExternalSystem", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateExternalSystem" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateExternalSystemRequest" + }, + { + "name": "external_system", + "type": "google.cloud.securitycenter_v2.types.ExternalSystem" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.ExternalSystem", + "shortName": "update_external_system" + }, + "description": "Sample for UpdateExternalSystem", + "file": "securitycenter_v2_generated_security_center_update_external_system_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateExternalSystem_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_external_system_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.update_finding", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateFinding", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateFinding" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateFindingRequest" + }, + { + "name": "finding", + "type": "google.cloud.securitycenter_v2.types.Finding" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Finding", + "shortName": "update_finding" + }, + "description": "Sample for UpdateFinding", + "file": "securitycenter_v2_generated_security_center_update_finding_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateFinding_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_finding_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.update_finding", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateFinding", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateFinding" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateFindingRequest" + }, + { + "name": "finding", + "type": "google.cloud.securitycenter_v2.types.Finding" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Finding", + "shortName": "update_finding" + }, + "description": "Sample for UpdateFinding", + "file": "securitycenter_v2_generated_security_center_update_finding_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateFinding_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_finding_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.update_mute_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateMuteConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateMuteConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateMuteConfigRequest" + }, + { + "name": "mute_config", + "type": "google.cloud.securitycenter_v2.types.MuteConfig" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.MuteConfig", + "shortName": "update_mute_config" + }, + "description": "Sample for UpdateMuteConfig", + "file": "securitycenter_v2_generated_security_center_update_mute_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateMuteConfig_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_mute_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.update_mute_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateMuteConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateMuteConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateMuteConfigRequest" + }, + { + "name": "mute_config", + "type": "google.cloud.securitycenter_v2.types.MuteConfig" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.MuteConfig", + "shortName": "update_mute_config" + }, + "description": "Sample for UpdateMuteConfig", + "file": "securitycenter_v2_generated_security_center_update_mute_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateMuteConfig_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_mute_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.update_notification_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateNotificationConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateNotificationConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateNotificationConfigRequest" + }, + { + "name": "notification_config", + "type": "google.cloud.securitycenter_v2.types.NotificationConfig" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.NotificationConfig", + "shortName": "update_notification_config" + }, + "description": "Sample for UpdateNotificationConfig", + "file": "securitycenter_v2_generated_security_center_update_notification_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateNotificationConfig_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_notification_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.update_notification_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateNotificationConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateNotificationConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateNotificationConfigRequest" + }, + { + "name": "notification_config", + "type": "google.cloud.securitycenter_v2.types.NotificationConfig" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.NotificationConfig", + "shortName": "update_notification_config" + }, + "description": "Sample for UpdateNotificationConfig", + "file": "securitycenter_v2_generated_security_center_update_notification_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateNotificationConfig_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_notification_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.update_resource_value_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateResourceValueConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateResourceValueConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateResourceValueConfigRequest" + }, + { + "name": "resource_value_config", + "type": "google.cloud.securitycenter_v2.types.ResourceValueConfig" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.ResourceValueConfig", + "shortName": "update_resource_value_config" + }, + "description": "Sample for UpdateResourceValueConfig", + "file": "securitycenter_v2_generated_security_center_update_resource_value_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateResourceValueConfig_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_resource_value_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.update_resource_value_config", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateResourceValueConfig", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateResourceValueConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateResourceValueConfigRequest" + }, + { + "name": "resource_value_config", + "type": "google.cloud.securitycenter_v2.types.ResourceValueConfig" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.ResourceValueConfig", + "shortName": "update_resource_value_config" + }, + "description": "Sample for UpdateResourceValueConfig", + "file": "securitycenter_v2_generated_security_center_update_resource_value_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateResourceValueConfig_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_resource_value_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.update_security_marks", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateSecurityMarks", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateSecurityMarks" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateSecurityMarksRequest" + }, + { + "name": "security_marks", + "type": "google.cloud.securitycenter_v2.types.SecurityMarks" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.SecurityMarks", + "shortName": "update_security_marks" + }, + "description": "Sample for UpdateSecurityMarks", + "file": "securitycenter_v2_generated_security_center_update_security_marks_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateSecurityMarks_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_security_marks_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.update_security_marks", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateSecurityMarks", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateSecurityMarks" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateSecurityMarksRequest" + }, + { + "name": "security_marks", + "type": "google.cloud.securitycenter_v2.types.SecurityMarks" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.SecurityMarks", + "shortName": "update_security_marks" + }, + "description": "Sample for UpdateSecurityMarks", + "file": "securitycenter_v2_generated_security_center_update_security_marks_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateSecurityMarks_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_security_marks_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient", + "shortName": "SecurityCenterAsyncClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterAsyncClient.update_source", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateSource", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateSource" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateSourceRequest" + }, + { + "name": "source", + "type": "google.cloud.securitycenter_v2.types.Source" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Source", + "shortName": "update_source" + }, + "description": "Sample for UpdateSource", + "file": "securitycenter_v2_generated_security_center_update_source_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateSource_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_source_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient", + "shortName": "SecurityCenterClient" + }, + "fullName": "google.cloud.securitycenter_v2.SecurityCenterClient.update_source", + "method": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter.UpdateSource", + "service": { + "fullName": "google.cloud.securitycenter.v2.SecurityCenter", + "shortName": "SecurityCenter" + }, + "shortName": "UpdateSource" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.securitycenter_v2.types.UpdateSourceRequest" + }, + { + "name": "source", + "type": "google.cloud.securitycenter_v2.types.Source" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.securitycenter_v2.types.Source", + "shortName": "update_source" + }, + "description": "Sample for UpdateSource", + "file": "securitycenter_v2_generated_security_center_update_source_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "securitycenter_v2_generated_SecurityCenter_UpdateSource_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "securitycenter_v2_generated_security_center_update_source_sync.py" + } + ] +} diff --git a/packages/google-cloud-securitycenter/scripts/fixup_securitycenter_v2_keywords.py b/packages/google-cloud-securitycenter/scripts/fixup_securitycenter_v2_keywords.py new file mode 100644 index 000000000000..9fab77ce6ce8 --- /dev/null +++ b/packages/google-cloud-securitycenter/scripts/fixup_securitycenter_v2_keywords.py @@ -0,0 +1,215 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +class securitycenterCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'batch_create_resource_value_configs': ('parent', 'requests', ), + 'bulk_mute_findings': ('parent', 'filter', ), + 'create_big_query_export': ('parent', 'big_query_export', 'big_query_export_id', ), + 'create_finding': ('parent', 'finding_id', 'finding', ), + 'create_mute_config': ('parent', 'mute_config', 'mute_config_id', ), + 'create_notification_config': ('parent', 'config_id', 'notification_config', ), + 'create_source': ('parent', 'source', ), + 'delete_big_query_export': ('name', ), + 'delete_mute_config': ('name', ), + 'delete_notification_config': ('name', ), + 'delete_resource_value_config': ('name', ), + 'get_big_query_export': ('name', ), + 'get_iam_policy': ('resource', 'options', ), + 'get_mute_config': ('name', ), + 'get_notification_config': ('name', ), + 'get_resource_value_config': ('name', ), + 'get_simulation': ('name', ), + 'get_source': ('name', ), + 'get_valued_resource': ('name', ), + 'group_findings': ('parent', 'group_by', 'filter', 'page_token', 'page_size', ), + 'list_attack_paths': ('parent', 'filter', 'page_token', 'page_size', ), + 'list_big_query_exports': ('parent', 'page_size', 'page_token', ), + 'list_findings': ('parent', 'filter', 'order_by', 'field_mask', 'page_token', 'page_size', ), + 'list_mute_configs': ('parent', 'page_size', 'page_token', ), + 'list_notification_configs': ('parent', 'page_token', 'page_size', ), + 'list_resource_value_configs': ('parent', 'page_size', 'page_token', ), + 'list_sources': ('parent', 'page_token', 'page_size', ), + 'list_valued_resources': ('parent', 'filter', 'page_token', 'page_size', 'order_by', ), + 'set_finding_state': ('name', 'state', ), + 'set_iam_policy': ('resource', 'policy', 'update_mask', ), + 'set_mute': ('name', 'mute', ), + 'test_iam_permissions': ('resource', 'permissions', ), + 'update_big_query_export': ('big_query_export', 'update_mask', ), + 'update_external_system': ('external_system', 'update_mask', ), + 'update_finding': ('finding', 'update_mask', ), + 'update_mute_config': ('mute_config', 'update_mask', ), + 'update_notification_config': ('notification_config', 'update_mask', ), + 'update_resource_value_config': ('resource_value_config', 'update_mask', ), + 'update_security_marks': ('security_marks', 'update_mask', ), + 'update_source': ('source', 'update_mask', ), + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=securitycenterCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the securitycenter client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/packages/google-cloud-securitycenter/setup.py b/packages/google-cloud-securitycenter/setup.py index f3059947e82c..965683ea548c 100644 --- a/packages/google-cloud-securitycenter/setup.py +++ b/packages/google-cloud-securitycenter/setup.py @@ -42,7 +42,9 @@ dependencies = [ "google-api-core[grpc] >= 1.34.1, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", - "google-auth >= 2.14.1, <3.0.0dev", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", "proto-plus >= 1.22.3, <2.0.0dev", "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "grpc-google-iam-v1 >= 0.12.4, <1.0.0dev", diff --git a/packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v1/test_security_center.py b/packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v1/test_security_center.py index 862bbc63f28a..f33bc5a05e03 100644 --- a/packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v1/test_security_center.py +++ b/packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v1/test_security_center.py @@ -93,6 +93,8 @@ kernel_rootkit, kubernetes, label, + load_balancer, + log_entry, mitre_attack, ) from google.cloud.securitycenter_v1.types import external_system as gcs_external_system @@ -114,6 +116,7 @@ from google.cloud.securitycenter_v1.types import mute_config from google.cloud.securitycenter_v1.types import mute_config as gcs_mute_config from google.cloud.securitycenter_v1.types import notification_config +from google.cloud.securitycenter_v1.types import org_policy from google.cloud.securitycenter_v1.types import organization_settings from google.cloud.securitycenter_v1.types import security_marks from google.cloud.securitycenter_v1.types import securitycenter_service @@ -16229,6 +16232,7 @@ def test_create_finding_rest(request_type): ], }, "yara_rule_signature": {"yara_rule": "yara_rule_value"}, + "signature_type": 1, } ], "uris": ["uris_value1", "uris_value2"], @@ -16249,15 +16253,31 @@ def test_create_finding_rest(request_type): "availability_impact": 1, }, "upstream_fix_available": True, - } + "impact": 1, + "exploitation_activity": 1, + "observed_in_the_wild": True, + "zero_day": True, + }, + "offending_package": { + "package_name": "package_name_value", + "cpe_uri": "cpe_uri_value", + "package_type": "package_type_value", + "package_version": "package_version_value", + }, + "fixed_package": {}, + "security_bulletin": { + "bulletin_id": "bulletin_id_value", + "submission_time": {}, + "suggested_upgrade_version": "suggested_upgrade_version_value", + }, }, "mute_update_time": {}, "external_systems": {}, "mitre_attack": { "primary_tactic": 1, - "primary_techniques": [1], + "primary_techniques": [49], "additional_tactics": [1], - "additional_techniques": [1], + "additional_techniques": [49], "version": "version_value", }, "access": { @@ -16298,6 +16318,10 @@ def test_create_finding_rest(request_type): "hashed_size": 1159, "partially_hashed": True, "contents": "contents_value", + "disk_path": { + "partition_uuid": "partition_uuid_value", + "relative_path": "relative_path_value", + }, }, "libraries": {}, "script": {}, @@ -16327,6 +16351,7 @@ def test_create_finding_rest(request_type): } ], "targets": {}, + "total_exfiltrated_bytes": 2469, }, "iam_bindings": [{"action": 1, "role": "role_value", "member": "member_value"}], "next_steps": "next_steps_value", @@ -16337,6 +16362,7 @@ def test_create_finding_rest(request_type): "uri": "uri_value", "image_id": "image_id_value", "labels": [{"name": "name_value", "value": "value_value"}], + "create_time": {}, } ], "kubernetes": { @@ -16365,6 +16391,15 @@ def test_create_finding_rest(request_type): "version": "version_value", } ], + "objects": [ + { + "group": "group_value", + "kind": "kind_value", + "ns": "ns_value", + "name": "name_value", + "containers": {}, + } + ], }, "database": { "name": "name_value", @@ -16372,6 +16407,7 @@ def test_create_finding_rest(request_type): "user_name": "user_name_value", "query": "query_value", "grantees": ["grantees_value1", "grantees_value2"], + "version": "version_value", }, "files": {}, "cloud_dlp_inspection": { @@ -16395,6 +16431,7 @@ def test_create_finding_rest(request_type): "unexpected_interrupt_handler": True, "unexpected_processes_in_runqueue": True, }, + "org_policies": [{"name": "name_value"}], "application": {"base_uri": "base_uri_value", "full_uri": "full_uri_value"}, "backup_disaster_recovery": { "backup_template": "backup_template_value", @@ -16408,6 +16445,17 @@ def test_create_finding_rest(request_type): "backup_type": "backup_type_value", "backup_create_time": {}, }, + "log_entries": [ + { + "cloud_logging_entry": { + "insert_id": "insert_id_value", + "log_id": "log_id_value", + "resource_container": "resource_container_value", + "timestamp": {}, + } + } + ], + "load_balancers": [{"name": "name_value"}], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -26144,6 +26192,7 @@ def test_update_finding_rest(request_type): ], }, "yara_rule_signature": {"yara_rule": "yara_rule_value"}, + "signature_type": 1, } ], "uris": ["uris_value1", "uris_value2"], @@ -26164,15 +26213,31 @@ def test_update_finding_rest(request_type): "availability_impact": 1, }, "upstream_fix_available": True, - } + "impact": 1, + "exploitation_activity": 1, + "observed_in_the_wild": True, + "zero_day": True, + }, + "offending_package": { + "package_name": "package_name_value", + "cpe_uri": "cpe_uri_value", + "package_type": "package_type_value", + "package_version": "package_version_value", + }, + "fixed_package": {}, + "security_bulletin": { + "bulletin_id": "bulletin_id_value", + "submission_time": {}, + "suggested_upgrade_version": "suggested_upgrade_version_value", + }, }, "mute_update_time": {}, "external_systems": {}, "mitre_attack": { "primary_tactic": 1, - "primary_techniques": [1], + "primary_techniques": [49], "additional_tactics": [1], - "additional_techniques": [1], + "additional_techniques": [49], "version": "version_value", }, "access": { @@ -26213,6 +26278,10 @@ def test_update_finding_rest(request_type): "hashed_size": 1159, "partially_hashed": True, "contents": "contents_value", + "disk_path": { + "partition_uuid": "partition_uuid_value", + "relative_path": "relative_path_value", + }, }, "libraries": {}, "script": {}, @@ -26242,6 +26311,7 @@ def test_update_finding_rest(request_type): } ], "targets": {}, + "total_exfiltrated_bytes": 2469, }, "iam_bindings": [{"action": 1, "role": "role_value", "member": "member_value"}], "next_steps": "next_steps_value", @@ -26252,6 +26322,7 @@ def test_update_finding_rest(request_type): "uri": "uri_value", "image_id": "image_id_value", "labels": [{"name": "name_value", "value": "value_value"}], + "create_time": {}, } ], "kubernetes": { @@ -26280,6 +26351,15 @@ def test_update_finding_rest(request_type): "version": "version_value", } ], + "objects": [ + { + "group": "group_value", + "kind": "kind_value", + "ns": "ns_value", + "name": "name_value", + "containers": {}, + } + ], }, "database": { "name": "name_value", @@ -26287,6 +26367,7 @@ def test_update_finding_rest(request_type): "user_name": "user_name_value", "query": "query_value", "grantees": ["grantees_value1", "grantees_value2"], + "version": "version_value", }, "files": {}, "cloud_dlp_inspection": { @@ -26310,6 +26391,7 @@ def test_update_finding_rest(request_type): "unexpected_interrupt_handler": True, "unexpected_processes_in_runqueue": True, }, + "org_policies": [{"name": "name_value"}], "application": {"base_uri": "base_uri_value", "full_uri": "full_uri_value"}, "backup_disaster_recovery": { "backup_template": "backup_template_value", @@ -26323,6 +26405,17 @@ def test_update_finding_rest(request_type): "backup_type": "backup_type_value", "backup_create_time": {}, }, + "log_entries": [ + { + "cloud_logging_entry": { + "insert_id": "insert_id_value", + "log_id": "log_id_value", + "resource_container": "resource_container_value", + "timestamp": {}, + } + } + ], + "load_balancers": [{"name": "name_value"}], } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -31252,9 +31345,32 @@ def test_parse_organization_settings_path(): assert expected == actual -def test_security_health_analytics_custom_module_path(): +def test_policy_path(): organization = "oyster" - custom_module = "nudibranch" + constraint_name = "nudibranch" + expected = "organizations/{organization}/policies/{constraint_name}".format( + organization=organization, + constraint_name=constraint_name, + ) + actual = SecurityCenterClient.policy_path(organization, constraint_name) + assert expected == actual + + +def test_parse_policy_path(): + expected = { + "organization": "cuttlefish", + "constraint_name": "mussel", + } + path = SecurityCenterClient.policy_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_policy_path(path) + assert expected == actual + + +def test_security_health_analytics_custom_module_path(): + organization = "winkle" + custom_module = "nautilus" expected = "organizations/{organization}/securityHealthAnalyticsSettings/customModules/{custom_module}".format( organization=organization, custom_module=custom_module, @@ -31267,8 +31383,8 @@ def test_security_health_analytics_custom_module_path(): def test_parse_security_health_analytics_custom_module_path(): expected = { - "organization": "cuttlefish", - "custom_module": "mussel", + "organization": "scallop", + "custom_module": "abalone", } path = SecurityCenterClient.security_health_analytics_custom_module_path(**expected) @@ -31280,8 +31396,8 @@ def test_parse_security_health_analytics_custom_module_path(): def test_security_marks_path(): - organization = "winkle" - asset = "nautilus" + organization = "squid" + asset = "clam" expected = "organizations/{organization}/assets/{asset}/securityMarks".format( organization=organization, asset=asset, @@ -31292,8 +31408,8 @@ def test_security_marks_path(): def test_parse_security_marks_path(): expected = { - "organization": "scallop", - "asset": "abalone", + "organization": "whelk", + "asset": "octopus", } path = SecurityCenterClient.security_marks_path(**expected) @@ -31303,8 +31419,8 @@ def test_parse_security_marks_path(): def test_source_path(): - organization = "squid" - source = "clam" + organization = "oyster" + source = "nudibranch" expected = "organizations/{organization}/sources/{source}".format( organization=organization, source=source, @@ -31315,8 +31431,8 @@ def test_source_path(): def test_parse_source_path(): expected = { - "organization": "whelk", - "source": "octopus", + "organization": "cuttlefish", + "source": "mussel", } path = SecurityCenterClient.source_path(**expected) @@ -31326,8 +31442,8 @@ def test_parse_source_path(): def test_table_data_profile_path(): - project = "oyster" - table_profile = "nudibranch" + project = "winkle" + table_profile = "nautilus" expected = "projects/{project}/tableProfiles/{table_profile}".format( project=project, table_profile=table_profile, @@ -31338,8 +31454,8 @@ def test_table_data_profile_path(): def test_parse_table_data_profile_path(): expected = { - "project": "cuttlefish", - "table_profile": "mussel", + "project": "scallop", + "table_profile": "abalone", } path = SecurityCenterClient.table_data_profile_path(**expected) @@ -31349,8 +31465,8 @@ def test_parse_table_data_profile_path(): def test_topic_path(): - project = "winkle" - topic = "nautilus" + project = "squid" + topic = "clam" expected = "projects/{project}/topics/{topic}".format( project=project, topic=topic, @@ -31361,8 +31477,8 @@ def test_topic_path(): def test_parse_topic_path(): expected = { - "project": "scallop", - "topic": "abalone", + "project": "whelk", + "topic": "octopus", } path = SecurityCenterClient.topic_path(**expected) @@ -31372,7 +31488,7 @@ def test_parse_topic_path(): def test_common_billing_account_path(): - billing_account = "squid" + billing_account = "oyster" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -31382,7 +31498,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "clam", + "billing_account": "nudibranch", } path = SecurityCenterClient.common_billing_account_path(**expected) @@ -31392,7 +31508,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "whelk" + folder = "cuttlefish" expected = "folders/{folder}".format( folder=folder, ) @@ -31402,7 +31518,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "octopus", + "folder": "mussel", } path = SecurityCenterClient.common_folder_path(**expected) @@ -31412,7 +31528,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "oyster" + organization = "winkle" expected = "organizations/{organization}".format( organization=organization, ) @@ -31422,7 +31538,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "nudibranch", + "organization": "nautilus", } path = SecurityCenterClient.common_organization_path(**expected) @@ -31432,7 +31548,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "cuttlefish" + project = "scallop" expected = "projects/{project}".format( project=project, ) @@ -31442,7 +31558,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "mussel", + "project": "abalone", } path = SecurityCenterClient.common_project_path(**expected) @@ -31452,8 +31568,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "winkle" - location = "nautilus" + project = "squid" + location = "clam" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -31464,8 +31580,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "scallop", - "location": "abalone", + "project": "whelk", + "location": "octopus", } path = SecurityCenterClient.common_location_path(**expected) diff --git a/packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v2/__init__.py b/packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v2/__init__.py new file mode 100644 index 000000000000..89a37dc92c5a --- /dev/null +++ b/packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v2/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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/packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v2/test_security_center.py b/packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v2/test_security_center.py new file mode 100644 index 000000000000..39b042316a49 --- /dev/null +++ b/packages/google-cloud-securitycenter/tests/unit/gapic/securitycenter_v2/test_security_center.py @@ -0,0 +1,29017 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import Iterable +import json +import math + +from google.api_core import ( + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) +from google.api_core import api_core_version, client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import operation_async # type: ignore +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.iam.v1 import iam_policy_pb2 # type: ignore +from google.iam.v1 import options_pb2 # type: ignore +from google.iam.v1 import policy_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import json_format +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.type import expr_pb2 # type: ignore +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +from google.cloud.securitycenter_v2.services.security_center import ( + SecurityCenterAsyncClient, + SecurityCenterClient, + pagers, + transports, +) +from google.cloud.securitycenter_v2.types import ( + access, + application, + attack_exposure, + attack_path, + backup_disaster_recovery, + bigquery_export, + cloud_dlp_data_profile, + cloud_dlp_inspection, + compliance, + connection, + contact_details, + container, + database, + exfiltration, +) +from google.cloud.securitycenter_v2.types import ( + iam_binding, + indicator, + kernel_rootkit, + kubernetes, + label, + load_balancer, + log_entry, + mitre_attack, +) +from google.cloud.securitycenter_v2.types import ( + security_posture, + securitycenter_service, + simulation, +) +from google.cloud.securitycenter_v2.types import external_system as gcs_external_system +from google.cloud.securitycenter_v2.types import ( + notification_config as gcs_notification_config, +) +from google.cloud.securitycenter_v2.types import ( + resource_value_config as gcs_resource_value_config, +) +from google.cloud.securitycenter_v2.types import security_marks as gcs_security_marks +from google.cloud.securitycenter_v2.types import external_system +from google.cloud.securitycenter_v2.types import file +from google.cloud.securitycenter_v2.types import finding +from google.cloud.securitycenter_v2.types import finding as gcs_finding +from google.cloud.securitycenter_v2.types import mute_config +from google.cloud.securitycenter_v2.types import mute_config as gcs_mute_config +from google.cloud.securitycenter_v2.types import notification_config +from google.cloud.securitycenter_v2.types import org_policy, process +from google.cloud.securitycenter_v2.types import resource_value_config +from google.cloud.securitycenter_v2.types import security_marks +from google.cloud.securitycenter_v2.types import source +from google.cloud.securitycenter_v2.types import source as gcs_source +from google.cloud.securitycenter_v2.types import valued_resource, vulnerability + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert SecurityCenterClient._get_default_mtls_endpoint(None) is None + assert ( + SecurityCenterClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + SecurityCenterClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + SecurityCenterClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + SecurityCenterClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + SecurityCenterClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + ) + + +def test__read_environment_variables(): + assert SecurityCenterClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert SecurityCenterClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert SecurityCenterClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + SecurityCenterClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert SecurityCenterClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert SecurityCenterClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert SecurityCenterClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + SecurityCenterClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert SecurityCenterClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert SecurityCenterClient._get_client_cert_source(None, False) is None + assert ( + SecurityCenterClient._get_client_cert_source(mock_provided_cert_source, False) + is None + ) + assert ( + SecurityCenterClient._get_client_cert_source(mock_provided_cert_source, True) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + SecurityCenterClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + SecurityCenterClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + SecurityCenterClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SecurityCenterClient), +) +@mock.patch.object( + SecurityCenterAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SecurityCenterAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = SecurityCenterClient._DEFAULT_UNIVERSE + default_endpoint = SecurityCenterClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = SecurityCenterClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + SecurityCenterClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + SecurityCenterClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == SecurityCenterClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + SecurityCenterClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + SecurityCenterClient._get_api_endpoint(None, None, default_universe, "always") + == SecurityCenterClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + SecurityCenterClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == SecurityCenterClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + SecurityCenterClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + SecurityCenterClient._get_api_endpoint(None, None, default_universe, "never") + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + SecurityCenterClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + SecurityCenterClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + SecurityCenterClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + SecurityCenterClient._get_universe_domain(None, None) + == SecurityCenterClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + SecurityCenterClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (SecurityCenterClient, transports.SecurityCenterGrpcTransport, "grpc"), + (SecurityCenterClient, transports.SecurityCenterRestTransport, "rest"), + ], +) +def test__validate_universe_domain(client_class, transport_class, transport_name): + client = client_class( + transport=transport_class(credentials=ga_credentials.AnonymousCredentials()) + ) + assert client._validate_universe_domain() == True + + # Test the case when universe is already validated. + assert client._validate_universe_domain() == True + + if transport_name == "grpc": + # Test the case where credentials are provided by the + # `local_channel_credentials`. The default universes in both match. + channel = grpc.secure_channel( + "http://localhost/", grpc.local_channel_credentials() + ) + client = client_class(transport=transport_class(channel=channel)) + assert client._validate_universe_domain() == True + + # Test the case where credentials do not exist: e.g. a transport is provided + # with no credentials. Validation should still succeed because there is no + # mismatch with non-existent credentials. + channel = grpc.secure_channel( + "http://localhost/", grpc.local_channel_credentials() + ) + transport = transport_class(channel=channel) + transport._credentials = None + client = client_class(transport=transport) + assert client._validate_universe_domain() == True + + # TODO: This is needed to cater for older versions of google-auth + # Make this test unconditional once the minimum supported version of + # google-auth becomes 2.23.0 or higher. + google_auth_major, google_auth_minor = [ + int(part) for part in google.auth.__version__.split(".")[0:2] + ] + if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): + credentials = ga_credentials.AnonymousCredentials() + credentials._universe_domain = "foo.com" + # Test the case when there is a universe mismatch from the credentials. + client = client_class(transport=transport_class(credentials=credentials)) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert ( + str(excinfo.value) + == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + ) + + # Test the case when there is a universe mismatch from the client. + # + # TODO: Make this test unconditional once the minimum supported version of + # google-api-core becomes 2.15.0 or higher. + api_core_major, api_core_minor = [ + int(part) for part in api_core_version.__version__.split(".")[0:2] + ] + if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): + client = client_class( + client_options={"universe_domain": "bar.com"}, + transport=transport_class( + credentials=ga_credentials.AnonymousCredentials(), + ), + ) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert ( + str(excinfo.value) + == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + ) + + # Test that ValueError is raised if universe_domain is provided via client options and credentials is None + with pytest.raises(ValueError): + client._compare_universes("foo.bar", None) + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (SecurityCenterClient, "grpc"), + (SecurityCenterAsyncClient, "grpc_asyncio"), + (SecurityCenterClient, "rest"), + ], +) +def test_security_center_client_from_service_account_info(client_class, transport_name): + creds = ga_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, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "securitycenter.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://securitycenter.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.SecurityCenterGrpcTransport, "grpc"), + (transports.SecurityCenterGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.SecurityCenterRestTransport, "rest"), + ], +) +def test_security_center_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (SecurityCenterClient, "grpc"), + (SecurityCenterAsyncClient, "grpc_asyncio"), + (SecurityCenterClient, "rest"), + ], +) +def test_security_center_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "securitycenter.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://securitycenter.googleapis.com" + ) + + +def test_security_center_client_get_transport_class(): + transport = SecurityCenterClient.get_transport_class() + available_transports = [ + transports.SecurityCenterGrpcTransport, + transports.SecurityCenterRestTransport, + ] + assert transport in available_transports + + transport = SecurityCenterClient.get_transport_class("grpc") + assert transport == transports.SecurityCenterGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (SecurityCenterClient, transports.SecurityCenterGrpcTransport, "grpc"), + ( + SecurityCenterAsyncClient, + transports.SecurityCenterGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (SecurityCenterClient, transports.SecurityCenterRestTransport, "rest"), + ], +) +@mock.patch.object( + SecurityCenterClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SecurityCenterClient), +) +@mock.patch.object( + SecurityCenterAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SecurityCenterAsyncClient), +) +def test_security_center_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(SecurityCenterClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(SecurityCenterClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (SecurityCenterClient, transports.SecurityCenterGrpcTransport, "grpc", "true"), + ( + SecurityCenterAsyncClient, + transports.SecurityCenterGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (SecurityCenterClient, transports.SecurityCenterGrpcTransport, "grpc", "false"), + ( + SecurityCenterAsyncClient, + transports.SecurityCenterGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + (SecurityCenterClient, transports.SecurityCenterRestTransport, "rest", "true"), + (SecurityCenterClient, transports.SecurityCenterRestTransport, "rest", "false"), + ], +) +@mock.patch.object( + SecurityCenterClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SecurityCenterClient), +) +@mock.patch.object( + SecurityCenterAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SecurityCenterAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_security_center_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + 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, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + 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=True, + ): + with mock.patch( + "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_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + 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, + always_use_jwt_access=True, + api_audience=None, + ) + + # 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(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", [SecurityCenterClient, SecurityCenterAsyncClient] +) +@mock.patch.object( + SecurityCenterClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(SecurityCenterClient), +) +@mock.patch.object( + SecurityCenterAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(SecurityCenterAsyncClient), +) +def test_security_center_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize( + "client_class", [SecurityCenterClient, SecurityCenterAsyncClient] +) +@mock.patch.object( + SecurityCenterClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SecurityCenterClient), +) +@mock.patch.object( + SecurityCenterAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SecurityCenterAsyncClient), +) +def test_security_center_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = SecurityCenterClient._DEFAULT_UNIVERSE + default_endpoint = SecurityCenterClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = SecurityCenterClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (SecurityCenterClient, transports.SecurityCenterGrpcTransport, "grpc"), + ( + SecurityCenterAsyncClient, + transports.SecurityCenterGrpcAsyncIOTransport, + "grpc_asyncio", + ), + (SecurityCenterClient, transports.SecurityCenterRestTransport, "rest"), + ], +) +def test_security_center_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + SecurityCenterClient, + transports.SecurityCenterGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + SecurityCenterAsyncClient, + transports.SecurityCenterGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + (SecurityCenterClient, transports.SecurityCenterRestTransport, "rest", None), + ], +) +def test_security_center_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_security_center_client_client_options_from_dict(): + with mock.patch( + "google.cloud.securitycenter_v2.services.security_center.transports.SecurityCenterGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = SecurityCenterClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + SecurityCenterClient, + transports.SecurityCenterGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + SecurityCenterAsyncClient, + transports.SecurityCenterGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_security_center_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "securitycenter.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=None, + default_host="securitycenter.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.BatchCreateResourceValueConfigsRequest, + dict, + ], +) +def test_batch_create_resource_value_configs(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_resource_value_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + securitycenter_service.BatchCreateResourceValueConfigsResponse() + ) + response = client.batch_create_resource_value_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert ( + args[0] == securitycenter_service.BatchCreateResourceValueConfigsRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance( + response, securitycenter_service.BatchCreateResourceValueConfigsResponse + ) + + +def test_batch_create_resource_value_configs_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_resource_value_configs), "__call__" + ) as call: + client.batch_create_resource_value_configs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert ( + args[0] == securitycenter_service.BatchCreateResourceValueConfigsRequest() + ) + + +@pytest.mark.asyncio +async def test_batch_create_resource_value_configs_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.BatchCreateResourceValueConfigsRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_resource_value_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.BatchCreateResourceValueConfigsResponse() + ) + response = await client.batch_create_resource_value_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert ( + args[0] == securitycenter_service.BatchCreateResourceValueConfigsRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance( + response, securitycenter_service.BatchCreateResourceValueConfigsResponse + ) + + +@pytest.mark.asyncio +async def test_batch_create_resource_value_configs_async_from_dict(): + await test_batch_create_resource_value_configs_async(request_type=dict) + + +def test_batch_create_resource_value_configs_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.BatchCreateResourceValueConfigsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_resource_value_configs), "__call__" + ) as call: + call.return_value = ( + securitycenter_service.BatchCreateResourceValueConfigsResponse() + ) + client.batch_create_resource_value_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_batch_create_resource_value_configs_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.BatchCreateResourceValueConfigsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_resource_value_configs), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.BatchCreateResourceValueConfigsResponse() + ) + await client.batch_create_resource_value_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_batch_create_resource_value_configs_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_resource_value_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + securitycenter_service.BatchCreateResourceValueConfigsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_create_resource_value_configs( + parent="parent_value", + requests=[ + securitycenter_service.CreateResourceValueConfigRequest( + parent="parent_value" + ) + ], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].requests + mock_val = [ + securitycenter_service.CreateResourceValueConfigRequest( + parent="parent_value" + ) + ] + assert arg == mock_val + + +def test_batch_create_resource_value_configs_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_resource_value_configs( + securitycenter_service.BatchCreateResourceValueConfigsRequest(), + parent="parent_value", + requests=[ + securitycenter_service.CreateResourceValueConfigRequest( + parent="parent_value" + ) + ], + ) + + +@pytest.mark.asyncio +async def test_batch_create_resource_value_configs_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_resource_value_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + securitycenter_service.BatchCreateResourceValueConfigsResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.BatchCreateResourceValueConfigsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_create_resource_value_configs( + parent="parent_value", + requests=[ + securitycenter_service.CreateResourceValueConfigRequest( + parent="parent_value" + ) + ], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].requests + mock_val = [ + securitycenter_service.CreateResourceValueConfigRequest( + parent="parent_value" + ) + ] + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_batch_create_resource_value_configs_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_create_resource_value_configs( + securitycenter_service.BatchCreateResourceValueConfigsRequest(), + parent="parent_value", + requests=[ + securitycenter_service.CreateResourceValueConfigRequest( + parent="parent_value" + ) + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.BulkMuteFindingsRequest, + dict, + ], +) +def test_bulk_mute_findings(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.bulk_mute_findings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.bulk_mute_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.BulkMuteFindingsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_bulk_mute_findings_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.bulk_mute_findings), "__call__" + ) as call: + client.bulk_mute_findings() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.BulkMuteFindingsRequest() + + +@pytest.mark.asyncio +async def test_bulk_mute_findings_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.BulkMuteFindingsRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.bulk_mute_findings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.bulk_mute_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.BulkMuteFindingsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_bulk_mute_findings_async_from_dict(): + await test_bulk_mute_findings_async(request_type=dict) + + +def test_bulk_mute_findings_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.BulkMuteFindingsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.bulk_mute_findings), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.bulk_mute_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_bulk_mute_findings_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.BulkMuteFindingsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.bulk_mute_findings), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.bulk_mute_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_bulk_mute_findings_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.bulk_mute_findings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.bulk_mute_findings( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_bulk_mute_findings_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.bulk_mute_findings( + securitycenter_service.BulkMuteFindingsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_bulk_mute_findings_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.bulk_mute_findings), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.bulk_mute_findings( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_bulk_mute_findings_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.bulk_mute_findings( + securitycenter_service.BulkMuteFindingsRequest(), + parent="parent_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.CreateBigQueryExportRequest, + dict, + ], +) +def test_create_big_query_export(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = bigquery_export.BigQueryExport( + name="name_value", + description="description_value", + filter="filter_value", + dataset="dataset_value", + most_recent_editor="most_recent_editor_value", + principal="principal_value", + ) + response = client.create_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateBigQueryExportRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, bigquery_export.BigQueryExport) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.dataset == "dataset_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.principal == "principal_value" + + +def test_create_big_query_export_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_big_query_export), "__call__" + ) as call: + client.create_big_query_export() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateBigQueryExportRequest() + + +@pytest.mark.asyncio +async def test_create_big_query_export_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.CreateBigQueryExportRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + bigquery_export.BigQueryExport( + name="name_value", + description="description_value", + filter="filter_value", + dataset="dataset_value", + most_recent_editor="most_recent_editor_value", + principal="principal_value", + ) + ) + response = await client.create_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateBigQueryExportRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, bigquery_export.BigQueryExport) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.dataset == "dataset_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.principal == "principal_value" + + +@pytest.mark.asyncio +async def test_create_big_query_export_async_from_dict(): + await test_create_big_query_export_async(request_type=dict) + + +def test_create_big_query_export_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateBigQueryExportRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_big_query_export), "__call__" + ) as call: + call.return_value = bigquery_export.BigQueryExport() + client.create_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_big_query_export_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateBigQueryExportRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_big_query_export), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + bigquery_export.BigQueryExport() + ) + await client.create_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_create_big_query_export_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = bigquery_export.BigQueryExport() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_big_query_export( + parent="parent_value", + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + big_query_export_id="big_query_export_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].big_query_export + mock_val = bigquery_export.BigQueryExport(name="name_value") + assert arg == mock_val + arg = args[0].big_query_export_id + mock_val = "big_query_export_id_value" + assert arg == mock_val + + +def test_create_big_query_export_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_big_query_export( + securitycenter_service.CreateBigQueryExportRequest(), + parent="parent_value", + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + big_query_export_id="big_query_export_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_big_query_export_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = bigquery_export.BigQueryExport() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + bigquery_export.BigQueryExport() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_big_query_export( + parent="parent_value", + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + big_query_export_id="big_query_export_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].big_query_export + mock_val = bigquery_export.BigQueryExport(name="name_value") + assert arg == mock_val + arg = args[0].big_query_export_id + mock_val = "big_query_export_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_big_query_export_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_big_query_export( + securitycenter_service.CreateBigQueryExportRequest(), + parent="parent_value", + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + big_query_export_id="big_query_export_id_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.CreateFindingRequest, + dict, + ], +) +def test_create_finding(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_finding), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=gcs_finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=gcs_finding.Finding.Severity.CRITICAL, + mute=gcs_finding.Finding.Mute.MUTED, + finding_class=gcs_finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + response = client.create_finding(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateFindingRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == gcs_finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == gcs_finding.Finding.Severity.CRITICAL + assert response.mute == gcs_finding.Finding.Mute.MUTED + assert response.finding_class == gcs_finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +def test_create_finding_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_finding), "__call__") as call: + client.create_finding() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateFindingRequest() + + +@pytest.mark.asyncio +async def test_create_finding_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.CreateFindingRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_finding), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=gcs_finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=gcs_finding.Finding.Severity.CRITICAL, + mute=gcs_finding.Finding.Mute.MUTED, + finding_class=gcs_finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + ) + response = await client.create_finding(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateFindingRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == gcs_finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == gcs_finding.Finding.Severity.CRITICAL + assert response.mute == gcs_finding.Finding.Mute.MUTED + assert response.finding_class == gcs_finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +@pytest.mark.asyncio +async def test_create_finding_async_from_dict(): + await test_create_finding_async(request_type=dict) + + +def test_create_finding_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateFindingRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_finding), "__call__") as call: + call.return_value = gcs_finding.Finding() + client.create_finding(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_finding_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateFindingRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_finding), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcs_finding.Finding()) + await client.create_finding(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_create_finding_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_finding), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_finding.Finding() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_finding( + parent="parent_value", + finding=gcs_finding.Finding(name="name_value"), + finding_id="finding_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].finding + mock_val = gcs_finding.Finding(name="name_value") + assert arg == mock_val + arg = args[0].finding_id + mock_val = "finding_id_value" + assert arg == mock_val + + +def test_create_finding_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_finding( + securitycenter_service.CreateFindingRequest(), + parent="parent_value", + finding=gcs_finding.Finding(name="name_value"), + finding_id="finding_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_finding_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_finding), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_finding.Finding() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcs_finding.Finding()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_finding( + parent="parent_value", + finding=gcs_finding.Finding(name="name_value"), + finding_id="finding_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].finding + mock_val = gcs_finding.Finding(name="name_value") + assert arg == mock_val + arg = args[0].finding_id + mock_val = "finding_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_finding_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_finding( + securitycenter_service.CreateFindingRequest(), + parent="parent_value", + finding=gcs_finding.Finding(name="name_value"), + finding_id="finding_id_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.CreateMuteConfigRequest, + dict, + ], +) +def test_create_mute_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_mute_config.MuteConfig( + name="name_value", + description="description_value", + filter="filter_value", + most_recent_editor="most_recent_editor_value", + type_=gcs_mute_config.MuteConfig.MuteConfigType.STATIC, + ) + response = client.create_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateMuteConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_mute_config.MuteConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.type_ == gcs_mute_config.MuteConfig.MuteConfigType.STATIC + + +def test_create_mute_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_mute_config), "__call__" + ) as call: + client.create_mute_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateMuteConfigRequest() + + +@pytest.mark.asyncio +async def test_create_mute_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.CreateMuteConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_mute_config.MuteConfig( + name="name_value", + description="description_value", + filter="filter_value", + most_recent_editor="most_recent_editor_value", + type_=gcs_mute_config.MuteConfig.MuteConfigType.STATIC, + ) + ) + response = await client.create_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateMuteConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_mute_config.MuteConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.type_ == gcs_mute_config.MuteConfig.MuteConfigType.STATIC + + +@pytest.mark.asyncio +async def test_create_mute_config_async_from_dict(): + await test_create_mute_config_async(request_type=dict) + + +def test_create_mute_config_routing_parameters(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateMuteConfigRequest( + **{"parent": "projects/sample1/locations/sample2"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_mute_config), "__call__" + ) as call: + call.return_value = gcs_mute_config.MuteConfig() + client.create_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateMuteConfigRequest( + **{"parent": "organizations/sample1/locations/sample2"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_mute_config), "__call__" + ) as call: + call.return_value = gcs_mute_config.MuteConfig() + client.create_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateMuteConfigRequest( + **{"parent": "folders/sample1/locations/sample2"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_mute_config), "__call__" + ) as call: + call.return_value = gcs_mute_config.MuteConfig() + client.create_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + + +def test_create_mute_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_mute_config.MuteConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_mute_config( + parent="parent_value", + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + mute_config_id="mute_config_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].mute_config + mock_val = gcs_mute_config.MuteConfig(name="name_value") + assert arg == mock_val + arg = args[0].mute_config_id + mock_val = "mute_config_id_value" + assert arg == mock_val + + +def test_create_mute_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_mute_config( + securitycenter_service.CreateMuteConfigRequest(), + parent="parent_value", + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + mute_config_id="mute_config_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_mute_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_mute_config.MuteConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_mute_config.MuteConfig() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_mute_config( + parent="parent_value", + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + mute_config_id="mute_config_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].mute_config + mock_val = gcs_mute_config.MuteConfig(name="name_value") + assert arg == mock_val + arg = args[0].mute_config_id + mock_val = "mute_config_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_mute_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_mute_config( + securitycenter_service.CreateMuteConfigRequest(), + parent="parent_value", + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + mute_config_id="mute_config_id_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.CreateNotificationConfigRequest, + dict, + ], +) +def test_create_notification_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_notification_config.NotificationConfig( + name="name_value", + description="description_value", + pubsub_topic="pubsub_topic_value", + service_account="service_account_value", + ) + response = client.create_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateNotificationConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_notification_config.NotificationConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.pubsub_topic == "pubsub_topic_value" + assert response.service_account == "service_account_value" + + +def test_create_notification_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_notification_config), "__call__" + ) as call: + client.create_notification_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateNotificationConfigRequest() + + +@pytest.mark.asyncio +async def test_create_notification_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.CreateNotificationConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_notification_config.NotificationConfig( + name="name_value", + description="description_value", + pubsub_topic="pubsub_topic_value", + service_account="service_account_value", + ) + ) + response = await client.create_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateNotificationConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_notification_config.NotificationConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.pubsub_topic == "pubsub_topic_value" + assert response.service_account == "service_account_value" + + +@pytest.mark.asyncio +async def test_create_notification_config_async_from_dict(): + await test_create_notification_config_async(request_type=dict) + + +def test_create_notification_config_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateNotificationConfigRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_notification_config), "__call__" + ) as call: + call.return_value = gcs_notification_config.NotificationConfig() + client.create_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_notification_config_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateNotificationConfigRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_notification_config), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_notification_config.NotificationConfig() + ) + await client.create_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_create_notification_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_notification_config.NotificationConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_notification_config( + parent="parent_value", + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + config_id="config_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].notification_config + mock_val = gcs_notification_config.NotificationConfig(name="name_value") + assert arg == mock_val + arg = args[0].config_id + mock_val = "config_id_value" + assert arg == mock_val + + +def test_create_notification_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_notification_config( + securitycenter_service.CreateNotificationConfigRequest(), + parent="parent_value", + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + config_id="config_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_notification_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_notification_config.NotificationConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_notification_config.NotificationConfig() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_notification_config( + parent="parent_value", + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + config_id="config_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].notification_config + mock_val = gcs_notification_config.NotificationConfig(name="name_value") + assert arg == mock_val + arg = args[0].config_id + mock_val = "config_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_notification_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_notification_config( + securitycenter_service.CreateNotificationConfigRequest(), + parent="parent_value", + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + config_id="config_id_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.CreateSourceRequest, + dict, + ], +) +def test_create_source(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_source.Source( + name="name_value", + display_name="display_name_value", + description="description_value", + canonical_name="canonical_name_value", + ) + response = client.create_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateSourceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_source.Source) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.canonical_name == "canonical_name_value" + + +def test_create_source_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_source), "__call__") as call: + client.create_source() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateSourceRequest() + + +@pytest.mark.asyncio +async def test_create_source_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.CreateSourceRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_source.Source( + name="name_value", + display_name="display_name_value", + description="description_value", + canonical_name="canonical_name_value", + ) + ) + response = await client.create_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.CreateSourceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_source.Source) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.canonical_name == "canonical_name_value" + + +@pytest.mark.asyncio +async def test_create_source_async_from_dict(): + await test_create_source_async(request_type=dict) + + +def test_create_source_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateSourceRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_source), "__call__") as call: + call.return_value = gcs_source.Source() + client.create_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_source_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.CreateSourceRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_source), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcs_source.Source()) + await client.create_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_create_source_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_source.Source() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_source( + parent="parent_value", + source=gcs_source.Source(name="name_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].source + mock_val = gcs_source.Source(name="name_value") + assert arg == mock_val + + +def test_create_source_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_source( + securitycenter_service.CreateSourceRequest(), + parent="parent_value", + source=gcs_source.Source(name="name_value"), + ) + + +@pytest.mark.asyncio +async def test_create_source_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_source.Source() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcs_source.Source()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_source( + parent="parent_value", + source=gcs_source.Source(name="name_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].source + mock_val = gcs_source.Source(name="name_value") + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_source_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_source( + securitycenter_service.CreateSourceRequest(), + parent="parent_value", + source=gcs_source.Source(name="name_value"), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.DeleteBigQueryExportRequest, + dict, + ], +) +def test_delete_big_query_export(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteBigQueryExportRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_big_query_export_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_big_query_export), "__call__" + ) as call: + client.delete_big_query_export() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteBigQueryExportRequest() + + +@pytest.mark.asyncio +async def test_delete_big_query_export_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.DeleteBigQueryExportRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteBigQueryExportRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_big_query_export_async_from_dict(): + await test_delete_big_query_export_async(request_type=dict) + + +def test_delete_big_query_export_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.DeleteBigQueryExportRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_big_query_export), "__call__" + ) as call: + call.return_value = None + client.delete_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_big_query_export_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.DeleteBigQueryExportRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_big_query_export), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_big_query_export_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_big_query_export( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_big_query_export_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_big_query_export( + securitycenter_service.DeleteBigQueryExportRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_big_query_export_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_big_query_export( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_big_query_export_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_big_query_export( + securitycenter_service.DeleteBigQueryExportRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.DeleteMuteConfigRequest, + dict, + ], +) +def test_delete_mute_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteMuteConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_mute_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_mute_config), "__call__" + ) as call: + client.delete_mute_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteMuteConfigRequest() + + +@pytest.mark.asyncio +async def test_delete_mute_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.DeleteMuteConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteMuteConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_mute_config_async_from_dict(): + await test_delete_mute_config_async(request_type=dict) + + +def test_delete_mute_config_routing_parameters(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.DeleteMuteConfigRequest( + **{"name": "projects/sample1/locations/sample2/muteConfigs/sample3"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_mute_config), "__call__" + ) as call: + call.return_value = None + client.delete_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.DeleteMuteConfigRequest( + **{"name": "organizations/sample1/locations/sample2/muteConfigs/sample3"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_mute_config), "__call__" + ) as call: + call.return_value = None + client.delete_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.DeleteMuteConfigRequest( + **{"name": "folders/sample1/locations/sample2/muteConfigs/sample3"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_mute_config), "__call__" + ) as call: + call.return_value = None + client.delete_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + + +def test_delete_mute_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_mute_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_mute_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_mute_config( + securitycenter_service.DeleteMuteConfigRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_mute_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_mute_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_mute_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_mute_config( + securitycenter_service.DeleteMuteConfigRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.DeleteNotificationConfigRequest, + dict, + ], +) +def test_delete_notification_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteNotificationConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_notification_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_notification_config), "__call__" + ) as call: + client.delete_notification_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteNotificationConfigRequest() + + +@pytest.mark.asyncio +async def test_delete_notification_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.DeleteNotificationConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteNotificationConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_notification_config_async_from_dict(): + await test_delete_notification_config_async(request_type=dict) + + +def test_delete_notification_config_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.DeleteNotificationConfigRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_notification_config), "__call__" + ) as call: + call.return_value = None + client.delete_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_notification_config_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.DeleteNotificationConfigRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_notification_config), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_notification_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_notification_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_notification_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_notification_config( + securitycenter_service.DeleteNotificationConfigRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_notification_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_notification_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_notification_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_notification_config( + securitycenter_service.DeleteNotificationConfigRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.DeleteResourceValueConfigRequest, + dict, + ], +) +def test_delete_resource_value_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteResourceValueConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_resource_value_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_resource_value_config), "__call__" + ) as call: + client.delete_resource_value_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteResourceValueConfigRequest() + + +@pytest.mark.asyncio +async def test_delete_resource_value_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.DeleteResourceValueConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.DeleteResourceValueConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_resource_value_config_async_from_dict(): + await test_delete_resource_value_config_async(request_type=dict) + + +def test_delete_resource_value_config_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.DeleteResourceValueConfigRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_resource_value_config), "__call__" + ) as call: + call.return_value = None + client.delete_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_resource_value_config_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.DeleteResourceValueConfigRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_resource_value_config), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_resource_value_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_resource_value_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_resource_value_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_resource_value_config( + securitycenter_service.DeleteResourceValueConfigRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_resource_value_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_resource_value_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_resource_value_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_resource_value_config( + securitycenter_service.DeleteResourceValueConfigRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetBigQueryExportRequest, + dict, + ], +) +def test_get_big_query_export(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = bigquery_export.BigQueryExport( + name="name_value", + description="description_value", + filter="filter_value", + dataset="dataset_value", + most_recent_editor="most_recent_editor_value", + principal="principal_value", + ) + response = client.get_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetBigQueryExportRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, bigquery_export.BigQueryExport) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.dataset == "dataset_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.principal == "principal_value" + + +def test_get_big_query_export_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_big_query_export), "__call__" + ) as call: + client.get_big_query_export() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetBigQueryExportRequest() + + +@pytest.mark.asyncio +async def test_get_big_query_export_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.GetBigQueryExportRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + bigquery_export.BigQueryExport( + name="name_value", + description="description_value", + filter="filter_value", + dataset="dataset_value", + most_recent_editor="most_recent_editor_value", + principal="principal_value", + ) + ) + response = await client.get_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetBigQueryExportRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, bigquery_export.BigQueryExport) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.dataset == "dataset_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.principal == "principal_value" + + +@pytest.mark.asyncio +async def test_get_big_query_export_async_from_dict(): + await test_get_big_query_export_async(request_type=dict) + + +def test_get_big_query_export_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetBigQueryExportRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_big_query_export), "__call__" + ) as call: + call.return_value = bigquery_export.BigQueryExport() + client.get_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_big_query_export_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetBigQueryExportRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_big_query_export), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + bigquery_export.BigQueryExport() + ) + await client.get_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_big_query_export_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = bigquery_export.BigQueryExport() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_big_query_export( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_big_query_export_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_big_query_export( + securitycenter_service.GetBigQueryExportRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_big_query_export_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = bigquery_export.BigQueryExport() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + bigquery_export.BigQueryExport() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_big_query_export( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_big_query_export_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_big_query_export( + securitycenter_service.GetBigQueryExportRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetSimulationRequest, + dict, + ], +) +def test_get_simulation(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_simulation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = simulation.Simulation( + name="name_value", + ) + response = client.get_simulation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetSimulationRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, simulation.Simulation) + assert response.name == "name_value" + + +def test_get_simulation_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_simulation), "__call__") as call: + client.get_simulation() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetSimulationRequest() + + +@pytest.mark.asyncio +async def test_get_simulation_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.GetSimulationRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_simulation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + simulation.Simulation( + name="name_value", + ) + ) + response = await client.get_simulation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetSimulationRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, simulation.Simulation) + assert response.name == "name_value" + + +@pytest.mark.asyncio +async def test_get_simulation_async_from_dict(): + await test_get_simulation_async(request_type=dict) + + +def test_get_simulation_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetSimulationRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_simulation), "__call__") as call: + call.return_value = simulation.Simulation() + client.get_simulation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_simulation_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetSimulationRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_simulation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + simulation.Simulation() + ) + await client.get_simulation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_simulation_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_simulation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = simulation.Simulation() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_simulation( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_simulation_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_simulation( + securitycenter_service.GetSimulationRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_simulation_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_simulation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = simulation.Simulation() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + simulation.Simulation() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_simulation( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_simulation_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_simulation( + securitycenter_service.GetSimulationRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetValuedResourceRequest, + dict, + ], +) +def test_get_valued_resource(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_valued_resource), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = valued_resource.ValuedResource( + name="name_value", + resource="resource_value", + resource_type="resource_type_value", + display_name="display_name_value", + resource_value=valued_resource.ValuedResource.ResourceValue.RESOURCE_VALUE_LOW, + exposed_score=0.1395, + ) + response = client.get_valued_resource(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetValuedResourceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, valued_resource.ValuedResource) + assert response.name == "name_value" + assert response.resource == "resource_value" + assert response.resource_type == "resource_type_value" + assert response.display_name == "display_name_value" + assert ( + response.resource_value + == valued_resource.ValuedResource.ResourceValue.RESOURCE_VALUE_LOW + ) + assert math.isclose(response.exposed_score, 0.1395, rel_tol=1e-6) + + +def test_get_valued_resource_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_valued_resource), "__call__" + ) as call: + client.get_valued_resource() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetValuedResourceRequest() + + +@pytest.mark.asyncio +async def test_get_valued_resource_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.GetValuedResourceRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_valued_resource), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + valued_resource.ValuedResource( + name="name_value", + resource="resource_value", + resource_type="resource_type_value", + display_name="display_name_value", + resource_value=valued_resource.ValuedResource.ResourceValue.RESOURCE_VALUE_LOW, + exposed_score=0.1395, + ) + ) + response = await client.get_valued_resource(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetValuedResourceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, valued_resource.ValuedResource) + assert response.name == "name_value" + assert response.resource == "resource_value" + assert response.resource_type == "resource_type_value" + assert response.display_name == "display_name_value" + assert ( + response.resource_value + == valued_resource.ValuedResource.ResourceValue.RESOURCE_VALUE_LOW + ) + assert math.isclose(response.exposed_score, 0.1395, rel_tol=1e-6) + + +@pytest.mark.asyncio +async def test_get_valued_resource_async_from_dict(): + await test_get_valued_resource_async(request_type=dict) + + +def test_get_valued_resource_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetValuedResourceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_valued_resource), "__call__" + ) as call: + call.return_value = valued_resource.ValuedResource() + client.get_valued_resource(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_valued_resource_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetValuedResourceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_valued_resource), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + valued_resource.ValuedResource() + ) + await client.get_valued_resource(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_valued_resource_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_valued_resource), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = valued_resource.ValuedResource() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_valued_resource( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_valued_resource_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_valued_resource( + securitycenter_service.GetValuedResourceRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_valued_resource_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_valued_resource), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = valued_resource.ValuedResource() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + valued_resource.ValuedResource() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_valued_resource( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_valued_resource_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_valued_resource( + securitycenter_service.GetValuedResourceRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + iam_policy_pb2.GetIamPolicyRequest, + dict, + ], +) +def test_get_iam_policy(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # 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: + # Designate an appropriate return value for the call. + call.return_value = policy_pb2.Policy( + version=774, + etag=b"etag_blob", + ) + response = client.get_iam_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == iam_policy_pb2.GetIamPolicyRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, policy_pb2.Policy) + assert response.version == 774 + assert response.etag == b"etag_blob" + + +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 = SecurityCenterClient( + credentials=ga_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_pb2.GetIamPolicyRequest() + + +@pytest.mark.asyncio +async def test_get_iam_policy_async( + transport: str = "grpc_asyncio", request_type=iam_policy_pb2.GetIamPolicyRequest +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # 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: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + policy_pb2.Policy( + version=774, + etag=b"etag_blob", + ) + ) + response = await client.get_iam_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == iam_policy_pb2.GetIamPolicyRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, policy_pb2.Policy) + assert response.version == 774 + assert response.etag == b"etag_blob" + + +@pytest.mark.asyncio +async def test_get_iam_policy_async_from_dict(): + await test_get_iam_policy_async(request_type=dict) + + +def test_get_iam_policy_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = iam_policy_pb2.GetIamPolicyRequest() + + request.resource = "resource_value" + + # 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: + call.return_value = policy_pb2.Policy() + client.get_iam_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "resource=resource_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_iam_policy_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = iam_policy_pb2.GetIamPolicyRequest() + + request.resource = "resource_value" + + # 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: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(policy_pb2.Policy()) + await client.get_iam_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "resource=resource_value", + ) in kw["metadata"] + + +def test_get_iam_policy_from_dict_foreign(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # 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: + # Designate an appropriate return value for the call. + call.return_value = policy_pb2.Policy() + response = client.get_iam_policy( + request={ + "resource": "resource_value", + "options": options_pb2.GetPolicyOptions(requested_policy_version=2598), + } + ) + call.assert_called() + + +def test_get_iam_policy_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # 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: + # Designate an appropriate return value for the call. + call.return_value = policy_pb2.Policy() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_iam_policy( + resource="resource_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val + + +def test_get_iam_policy_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_iam_policy( + iam_policy_pb2.GetIamPolicyRequest(), + resource="resource_value", + ) + + +@pytest.mark.asyncio +async def test_get_iam_policy_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # 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: + # Designate an appropriate return value for the call. + call.return_value = policy_pb2.Policy() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(policy_pb2.Policy()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_iam_policy( + resource="resource_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_iam_policy_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_iam_policy( + iam_policy_pb2.GetIamPolicyRequest(), + resource="resource_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetMuteConfigRequest, + dict, + ], +) +def test_get_mute_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_mute_config), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = mute_config.MuteConfig( + name="name_value", + description="description_value", + filter="filter_value", + most_recent_editor="most_recent_editor_value", + type_=mute_config.MuteConfig.MuteConfigType.STATIC, + ) + response = client.get_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetMuteConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, mute_config.MuteConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.type_ == mute_config.MuteConfig.MuteConfigType.STATIC + + +def test_get_mute_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_mute_config), "__call__") as call: + client.get_mute_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetMuteConfigRequest() + + +@pytest.mark.asyncio +async def test_get_mute_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.GetMuteConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_mute_config), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + mute_config.MuteConfig( + name="name_value", + description="description_value", + filter="filter_value", + most_recent_editor="most_recent_editor_value", + type_=mute_config.MuteConfig.MuteConfigType.STATIC, + ) + ) + response = await client.get_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetMuteConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, mute_config.MuteConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.type_ == mute_config.MuteConfig.MuteConfigType.STATIC + + +@pytest.mark.asyncio +async def test_get_mute_config_async_from_dict(): + await test_get_mute_config_async(request_type=dict) + + +def test_get_mute_config_routing_parameters(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetMuteConfigRequest( + **{"name": "projects/sample1/locations/sample2/muteConfigs/sample3"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_mute_config), "__call__") as call: + call.return_value = mute_config.MuteConfig() + client.get_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetMuteConfigRequest( + **{"name": "organizations/sample1/locations/sample2/muteConfigs/sample3"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_mute_config), "__call__") as call: + call.return_value = mute_config.MuteConfig() + client.get_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetMuteConfigRequest( + **{"name": "folders/sample1/locations/sample2/muteConfigs/sample3"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_mute_config), "__call__") as call: + call.return_value = mute_config.MuteConfig() + client.get_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + + +def test_get_mute_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_mute_config), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = mute_config.MuteConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_mute_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_mute_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_mute_config( + securitycenter_service.GetMuteConfigRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_mute_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_mute_config), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = mute_config.MuteConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + mute_config.MuteConfig() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_mute_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_mute_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_mute_config( + securitycenter_service.GetMuteConfigRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetNotificationConfigRequest, + dict, + ], +) +def test_get_notification_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = notification_config.NotificationConfig( + name="name_value", + description="description_value", + pubsub_topic="pubsub_topic_value", + service_account="service_account_value", + ) + response = client.get_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetNotificationConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, notification_config.NotificationConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.pubsub_topic == "pubsub_topic_value" + assert response.service_account == "service_account_value" + + +def test_get_notification_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_notification_config), "__call__" + ) as call: + client.get_notification_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetNotificationConfigRequest() + + +@pytest.mark.asyncio +async def test_get_notification_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.GetNotificationConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + notification_config.NotificationConfig( + name="name_value", + description="description_value", + pubsub_topic="pubsub_topic_value", + service_account="service_account_value", + ) + ) + response = await client.get_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetNotificationConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, notification_config.NotificationConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.pubsub_topic == "pubsub_topic_value" + assert response.service_account == "service_account_value" + + +@pytest.mark.asyncio +async def test_get_notification_config_async_from_dict(): + await test_get_notification_config_async(request_type=dict) + + +def test_get_notification_config_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetNotificationConfigRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_notification_config), "__call__" + ) as call: + call.return_value = notification_config.NotificationConfig() + client.get_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_notification_config_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetNotificationConfigRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_notification_config), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + notification_config.NotificationConfig() + ) + await client.get_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_notification_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = notification_config.NotificationConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_notification_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_notification_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_notification_config( + securitycenter_service.GetNotificationConfigRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_notification_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = notification_config.NotificationConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + notification_config.NotificationConfig() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_notification_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_notification_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_notification_config( + securitycenter_service.GetNotificationConfigRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetResourceValueConfigRequest, + dict, + ], +) +def test_get_resource_value_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource_value_config.ResourceValueConfig( + name="name_value", + resource_value=resource_value_config.ResourceValue.HIGH, + tag_values=["tag_values_value"], + resource_type="resource_type_value", + scope="scope_value", + description="description_value", + ) + response = client.get_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetResourceValueConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, resource_value_config.ResourceValueConfig) + assert response.name == "name_value" + assert response.resource_value == resource_value_config.ResourceValue.HIGH + assert response.tag_values == ["tag_values_value"] + assert response.resource_type == "resource_type_value" + assert response.scope == "scope_value" + assert response.description == "description_value" + + +def test_get_resource_value_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_resource_value_config), "__call__" + ) as call: + client.get_resource_value_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetResourceValueConfigRequest() + + +@pytest.mark.asyncio +async def test_get_resource_value_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.GetResourceValueConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource_value_config.ResourceValueConfig( + name="name_value", + resource_value=resource_value_config.ResourceValue.HIGH, + tag_values=["tag_values_value"], + resource_type="resource_type_value", + scope="scope_value", + description="description_value", + ) + ) + response = await client.get_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetResourceValueConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, resource_value_config.ResourceValueConfig) + assert response.name == "name_value" + assert response.resource_value == resource_value_config.ResourceValue.HIGH + assert response.tag_values == ["tag_values_value"] + assert response.resource_type == "resource_type_value" + assert response.scope == "scope_value" + assert response.description == "description_value" + + +@pytest.mark.asyncio +async def test_get_resource_value_config_async_from_dict(): + await test_get_resource_value_config_async(request_type=dict) + + +def test_get_resource_value_config_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetResourceValueConfigRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_resource_value_config), "__call__" + ) as call: + call.return_value = resource_value_config.ResourceValueConfig() + client.get_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_resource_value_config_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetResourceValueConfigRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_resource_value_config), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource_value_config.ResourceValueConfig() + ) + await client.get_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_resource_value_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource_value_config.ResourceValueConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_resource_value_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_resource_value_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_resource_value_config( + securitycenter_service.GetResourceValueConfigRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_resource_value_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resource_value_config.ResourceValueConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resource_value_config.ResourceValueConfig() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_resource_value_config( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_resource_value_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_resource_value_config( + securitycenter_service.GetResourceValueConfigRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetSourceRequest, + dict, + ], +) +def test_get_source(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = source.Source( + name="name_value", + display_name="display_name_value", + description="description_value", + canonical_name="canonical_name_value", + ) + response = client.get_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetSourceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, source.Source) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.canonical_name == "canonical_name_value" + + +def test_get_source_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_source), "__call__") as call: + client.get_source() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetSourceRequest() + + +@pytest.mark.asyncio +async def test_get_source_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.GetSourceRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + source.Source( + name="name_value", + display_name="display_name_value", + description="description_value", + canonical_name="canonical_name_value", + ) + ) + response = await client.get_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GetSourceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, source.Source) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.canonical_name == "canonical_name_value" + + +@pytest.mark.asyncio +async def test_get_source_async_from_dict(): + await test_get_source_async(request_type=dict) + + +def test_get_source_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetSourceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_source), "__call__") as call: + call.return_value = source.Source() + client.get_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_source_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GetSourceRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_source), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(source.Source()) + await client.get_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_source_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = source.Source() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_source( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_source_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_source( + securitycenter_service.GetSourceRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_source_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = source.Source() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(source.Source()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_source( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_source_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_source( + securitycenter_service.GetSourceRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GroupFindingsRequest, + dict, + ], +) +def test_group_findings(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.group_findings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.GroupFindingsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + response = client.group_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GroupFindingsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.GroupFindingsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +def test_group_findings_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.group_findings), "__call__") as call: + client.group_findings() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GroupFindingsRequest() + + +@pytest.mark.asyncio +async def test_group_findings_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.GroupFindingsRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.group_findings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.GroupFindingsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + response = await client.group_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.GroupFindingsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.GroupFindingsAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.asyncio +async def test_group_findings_async_from_dict(): + await test_group_findings_async(request_type=dict) + + +def test_group_findings_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GroupFindingsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.group_findings), "__call__") as call: + call.return_value = securitycenter_service.GroupFindingsResponse() + client.group_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_group_findings_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.GroupFindingsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.group_findings), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.GroupFindingsResponse() + ) + await client.group_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_group_findings_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.group_findings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.GroupFindingsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.group_findings( + parent="parent_value", + group_by="group_by_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].group_by + mock_val = "group_by_value" + assert arg == mock_val + + +def test_group_findings_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.group_findings( + securitycenter_service.GroupFindingsRequest(), + parent="parent_value", + group_by="group_by_value", + ) + + +@pytest.mark.asyncio +async def test_group_findings_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.group_findings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.GroupFindingsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.GroupFindingsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.group_findings( + parent="parent_value", + group_by="group_by_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].group_by + mock_val = "group_by_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_group_findings_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.group_findings( + securitycenter_service.GroupFindingsRequest(), + parent="parent_value", + group_by="group_by_value", + ) + + +def test_group_findings_pager(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.group_findings), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + ], + next_page_token="abc", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[], + next_page_token="def", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + ], + next_page_token="ghi", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.group_findings(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, securitycenter_service.GroupResult) for i in results) + + +def test_group_findings_pages(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.group_findings), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + ], + next_page_token="abc", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[], + next_page_token="def", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + ], + next_page_token="ghi", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + ], + ), + RuntimeError, + ) + pages = list(client.group_findings(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_group_findings_async_pager(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.group_findings), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + ], + next_page_token="abc", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[], + next_page_token="def", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + ], + next_page_token="ghi", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + ], + ), + RuntimeError, + ) + async_pager = await client.group_findings( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, securitycenter_service.GroupResult) for i in responses) + + +@pytest.mark.asyncio +async def test_group_findings_async_pages(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.group_findings), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + ], + next_page_token="abc", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[], + next_page_token="def", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + ], + next_page_token="ghi", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.group_findings(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListAttackPathsRequest, + dict, + ], +) +def test_list_attack_paths(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListAttackPathsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_attack_paths(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListAttackPathsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAttackPathsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_attack_paths_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), "__call__" + ) as call: + client.list_attack_paths() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListAttackPathsRequest() + + +@pytest.mark.asyncio +async def test_list_attack_paths_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.ListAttackPathsRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListAttackPathsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_attack_paths(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListAttackPathsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAttackPathsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_attack_paths_async_from_dict(): + await test_list_attack_paths_async(request_type=dict) + + +def test_list_attack_paths_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListAttackPathsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), "__call__" + ) as call: + call.return_value = securitycenter_service.ListAttackPathsResponse() + client.list_attack_paths(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_attack_paths_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListAttackPathsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListAttackPathsResponse() + ) + await client.list_attack_paths(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_attack_paths_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListAttackPathsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_attack_paths( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_attack_paths_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_attack_paths( + securitycenter_service.ListAttackPathsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_attack_paths_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListAttackPathsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListAttackPathsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_attack_paths( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_attack_paths_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_attack_paths( + securitycenter_service.ListAttackPathsRequest(), + parent="parent_value", + ) + + +def test_list_attack_paths_pager(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + attack_path.AttackPath(), + attack_path.AttackPath(), + ], + next_page_token="abc", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[], + next_page_token="def", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + attack_path.AttackPath(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_attack_paths(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, attack_path.AttackPath) for i in results) + + +def test_list_attack_paths_pages(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + attack_path.AttackPath(), + attack_path.AttackPath(), + ], + next_page_token="abc", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[], + next_page_token="def", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + attack_path.AttackPath(), + ], + ), + RuntimeError, + ) + pages = list(client.list_attack_paths(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_attack_paths_async_pager(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + attack_path.AttackPath(), + attack_path.AttackPath(), + ], + next_page_token="abc", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[], + next_page_token="def", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + attack_path.AttackPath(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_attack_paths( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, attack_path.AttackPath) for i in responses) + + +@pytest.mark.asyncio +async def test_list_attack_paths_async_pages(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_attack_paths), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + attack_path.AttackPath(), + attack_path.AttackPath(), + ], + next_page_token="abc", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[], + next_page_token="def", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + attack_path.AttackPath(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_attack_paths(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListBigQueryExportsRequest, + dict, + ], +) +def test_list_big_query_exports(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListBigQueryExportsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_big_query_exports(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListBigQueryExportsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListBigQueryExportsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_big_query_exports_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), "__call__" + ) as call: + client.list_big_query_exports() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListBigQueryExportsRequest() + + +@pytest.mark.asyncio +async def test_list_big_query_exports_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.ListBigQueryExportsRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListBigQueryExportsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_big_query_exports(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListBigQueryExportsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListBigQueryExportsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_big_query_exports_async_from_dict(): + await test_list_big_query_exports_async(request_type=dict) + + +def test_list_big_query_exports_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListBigQueryExportsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), "__call__" + ) as call: + call.return_value = securitycenter_service.ListBigQueryExportsResponse() + client.list_big_query_exports(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_big_query_exports_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListBigQueryExportsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListBigQueryExportsResponse() + ) + await client.list_big_query_exports(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_big_query_exports_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListBigQueryExportsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_big_query_exports( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_big_query_exports_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_big_query_exports( + securitycenter_service.ListBigQueryExportsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_big_query_exports_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListBigQueryExportsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListBigQueryExportsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_big_query_exports( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_big_query_exports_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_big_query_exports( + securitycenter_service.ListBigQueryExportsRequest(), + parent="parent_value", + ) + + +def test_list_big_query_exports_pager(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + ], + next_page_token="abc", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[], + next_page_token="def", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_big_query_exports(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, bigquery_export.BigQueryExport) for i in results) + + +def test_list_big_query_exports_pages(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + ], + next_page_token="abc", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[], + next_page_token="def", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + ], + ), + RuntimeError, + ) + pages = list(client.list_big_query_exports(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_big_query_exports_async_pager(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + ], + next_page_token="abc", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[], + next_page_token="def", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_big_query_exports( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, bigquery_export.BigQueryExport) for i in responses) + + +@pytest.mark.asyncio +async def test_list_big_query_exports_async_pages(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_big_query_exports), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + ], + next_page_token="abc", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[], + next_page_token="def", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_big_query_exports(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListFindingsRequest, + dict, + ], +) +def test_list_findings(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_findings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListFindingsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + response = client.list_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListFindingsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListFindingsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +def test_list_findings_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_findings), "__call__") as call: + client.list_findings() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListFindingsRequest() + + +@pytest.mark.asyncio +async def test_list_findings_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.ListFindingsRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_findings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListFindingsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + response = await client.list_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListFindingsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListFindingsAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.asyncio +async def test_list_findings_async_from_dict(): + await test_list_findings_async(request_type=dict) + + +def test_list_findings_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListFindingsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_findings), "__call__") as call: + call.return_value = securitycenter_service.ListFindingsResponse() + client.list_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_findings_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListFindingsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_findings), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListFindingsResponse() + ) + await client.list_findings(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_findings_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_findings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListFindingsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_findings( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_findings_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_findings( + securitycenter_service.ListFindingsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_findings_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_findings), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListFindingsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListFindingsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_findings( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_findings_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_findings( + securitycenter_service.ListFindingsRequest(), + parent="parent_value", + ) + + +def test_list_findings_pager(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_findings), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + next_page_token="abc", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[], + next_page_token="def", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_findings(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance( + i, securitycenter_service.ListFindingsResponse.ListFindingsResult + ) + for i in results + ) + + +def test_list_findings_pages(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_findings), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + next_page_token="abc", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[], + next_page_token="def", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + ), + RuntimeError, + ) + pages = list(client.list_findings(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_findings_async_pager(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_findings), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + next_page_token="abc", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[], + next_page_token="def", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_findings( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance( + i, securitycenter_service.ListFindingsResponse.ListFindingsResult + ) + for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_findings_async_pages(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_findings), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + next_page_token="abc", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[], + next_page_token="def", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_findings(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListMuteConfigsRequest, + dict, + ], +) +def test_list_mute_configs(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListMuteConfigsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_mute_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListMuteConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListMuteConfigsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_mute_configs_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), "__call__" + ) as call: + client.list_mute_configs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListMuteConfigsRequest() + + +@pytest.mark.asyncio +async def test_list_mute_configs_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.ListMuteConfigsRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListMuteConfigsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_mute_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListMuteConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListMuteConfigsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_mute_configs_async_from_dict(): + await test_list_mute_configs_async(request_type=dict) + + +def test_list_mute_configs_routing_parameters(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListMuteConfigsRequest( + **{"parent": "projects/sample1/locations/sample2/muteConfigs"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), "__call__" + ) as call: + call.return_value = securitycenter_service.ListMuteConfigsResponse() + client.list_mute_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListMuteConfigsRequest( + **{"parent": "organizations/sample1/locations/sample2/muteConfigs"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), "__call__" + ) as call: + call.return_value = securitycenter_service.ListMuteConfigsResponse() + client.list_mute_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListMuteConfigsRequest( + **{"parent": "folders/sample1/locations/sample2/muteConfigs"} + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), "__call__" + ) as call: + call.return_value = securitycenter_service.ListMuteConfigsResponse() + client.list_mute_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + + +def test_list_mute_configs_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListMuteConfigsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_mute_configs( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_mute_configs_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_mute_configs( + securitycenter_service.ListMuteConfigsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_mute_configs_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListMuteConfigsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListMuteConfigsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_mute_configs( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_mute_configs_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_mute_configs( + securitycenter_service.ListMuteConfigsRequest(), + parent="parent_value", + ) + + +def test_list_mute_configs_pager(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + mute_config.MuteConfig(), + mute_config.MuteConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[], + next_page_token="def", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + mute_config.MuteConfig(), + ], + ), + RuntimeError, + ) + + metadata = () + pager = client.list_mute_configs(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, mute_config.MuteConfig) for i in results) + + +def test_list_mute_configs_pages(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + mute_config.MuteConfig(), + mute_config.MuteConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[], + next_page_token="def", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + mute_config.MuteConfig(), + ], + ), + RuntimeError, + ) + pages = list(client.list_mute_configs(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_mute_configs_async_pager(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + mute_config.MuteConfig(), + mute_config.MuteConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[], + next_page_token="def", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + mute_config.MuteConfig(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_mute_configs( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, mute_config.MuteConfig) for i in responses) + + +@pytest.mark.asyncio +async def test_list_mute_configs_async_pages(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_mute_configs), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + mute_config.MuteConfig(), + mute_config.MuteConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[], + next_page_token="def", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + mute_config.MuteConfig(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_mute_configs(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListNotificationConfigsRequest, + dict, + ], +) +def test_list_notification_configs(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListNotificationConfigsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_notification_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListNotificationConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNotificationConfigsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_notification_configs_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), "__call__" + ) as call: + client.list_notification_configs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListNotificationConfigsRequest() + + +@pytest.mark.asyncio +async def test_list_notification_configs_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.ListNotificationConfigsRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListNotificationConfigsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_notification_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListNotificationConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNotificationConfigsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_notification_configs_async_from_dict(): + await test_list_notification_configs_async(request_type=dict) + + +def test_list_notification_configs_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListNotificationConfigsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), "__call__" + ) as call: + call.return_value = securitycenter_service.ListNotificationConfigsResponse() + client.list_notification_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_notification_configs_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListNotificationConfigsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListNotificationConfigsResponse() + ) + await client.list_notification_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_notification_configs_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListNotificationConfigsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_notification_configs( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_notification_configs_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_notification_configs( + securitycenter_service.ListNotificationConfigsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_notification_configs_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListNotificationConfigsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListNotificationConfigsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_notification_configs( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_notification_configs_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_notification_configs( + securitycenter_service.ListNotificationConfigsRequest(), + parent="parent_value", + ) + + +def test_list_notification_configs_pager(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[], + next_page_token="def", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_notification_configs(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, notification_config.NotificationConfig) for i in results + ) + + +def test_list_notification_configs_pages(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[], + next_page_token="def", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + ], + ), + RuntimeError, + ) + pages = list(client.list_notification_configs(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_notification_configs_async_pager(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[], + next_page_token="def", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_notification_configs( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, notification_config.NotificationConfig) for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_notification_configs_async_pages(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notification_configs), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[], + next_page_token="def", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_notification_configs(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListResourceValueConfigsRequest, + dict, + ], +) +def test_list_resource_value_configs(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListResourceValueConfigsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_resource_value_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListResourceValueConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListResourceValueConfigsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_resource_value_configs_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), "__call__" + ) as call: + client.list_resource_value_configs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListResourceValueConfigsRequest() + + +@pytest.mark.asyncio +async def test_list_resource_value_configs_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.ListResourceValueConfigsRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListResourceValueConfigsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_resource_value_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListResourceValueConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListResourceValueConfigsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_resource_value_configs_async_from_dict(): + await test_list_resource_value_configs_async(request_type=dict) + + +def test_list_resource_value_configs_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListResourceValueConfigsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), "__call__" + ) as call: + call.return_value = securitycenter_service.ListResourceValueConfigsResponse() + client.list_resource_value_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_resource_value_configs_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListResourceValueConfigsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListResourceValueConfigsResponse() + ) + await client.list_resource_value_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_resource_value_configs_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListResourceValueConfigsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_resource_value_configs( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_resource_value_configs_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_resource_value_configs( + securitycenter_service.ListResourceValueConfigsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_resource_value_configs_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListResourceValueConfigsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListResourceValueConfigsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_resource_value_configs( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_resource_value_configs_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_resource_value_configs( + securitycenter_service.ListResourceValueConfigsRequest(), + parent="parent_value", + ) + + +def test_list_resource_value_configs_pager(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[], + next_page_token="def", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_resource_value_configs(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, resource_value_config.ResourceValueConfig) for i in results + ) + + +def test_list_resource_value_configs_pages(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[], + next_page_token="def", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + ], + ), + RuntimeError, + ) + pages = list(client.list_resource_value_configs(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_resource_value_configs_async_pager(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[], + next_page_token="def", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_resource_value_configs( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, resource_value_config.ResourceValueConfig) for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_resource_value_configs_async_pages(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_resource_value_configs), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[], + next_page_token="def", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_resource_value_configs(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListSourcesRequest, + dict, + ], +) +def test_list_sources(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_sources), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListSourcesResponse( + next_page_token="next_page_token_value", + ) + response = client.list_sources(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListSourcesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSourcesPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_sources_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_sources), "__call__") as call: + client.list_sources() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListSourcesRequest() + + +@pytest.mark.asyncio +async def test_list_sources_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.ListSourcesRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_sources), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListSourcesResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_sources(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListSourcesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSourcesAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_sources_async_from_dict(): + await test_list_sources_async(request_type=dict) + + +def test_list_sources_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListSourcesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_sources), "__call__") as call: + call.return_value = securitycenter_service.ListSourcesResponse() + client.list_sources(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_sources_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListSourcesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_sources), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListSourcesResponse() + ) + await client.list_sources(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_sources_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_sources), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListSourcesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_sources( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_sources_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_sources( + securitycenter_service.ListSourcesRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_sources_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_sources), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListSourcesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListSourcesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_sources( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_sources_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_sources( + securitycenter_service.ListSourcesRequest(), + parent="parent_value", + ) + + +def test_list_sources_pager(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_sources), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + source.Source(), + source.Source(), + ], + next_page_token="abc", + ), + securitycenter_service.ListSourcesResponse( + sources=[], + next_page_token="def", + ), + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + source.Source(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_sources(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, source.Source) for i in results) + + +def test_list_sources_pages(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_sources), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + source.Source(), + source.Source(), + ], + next_page_token="abc", + ), + securitycenter_service.ListSourcesResponse( + sources=[], + next_page_token="def", + ), + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + source.Source(), + ], + ), + RuntimeError, + ) + pages = list(client.list_sources(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_sources_async_pager(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_sources), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + source.Source(), + source.Source(), + ], + next_page_token="abc", + ), + securitycenter_service.ListSourcesResponse( + sources=[], + next_page_token="def", + ), + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + source.Source(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_sources( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, source.Source) for i in responses) + + +@pytest.mark.asyncio +async def test_list_sources_async_pages(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_sources), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + source.Source(), + source.Source(), + ], + next_page_token="abc", + ), + securitycenter_service.ListSourcesResponse( + sources=[], + next_page_token="def", + ), + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + source.Source(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_sources(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListValuedResourcesRequest, + dict, + ], +) +def test_list_valued_resources(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListValuedResourcesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + response = client.list_valued_resources(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListValuedResourcesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListValuedResourcesPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +def test_list_valued_resources_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), "__call__" + ) as call: + client.list_valued_resources() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListValuedResourcesRequest() + + +@pytest.mark.asyncio +async def test_list_valued_resources_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.ListValuedResourcesRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListValuedResourcesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + ) + response = await client.list_valued_resources(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.ListValuedResourcesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListValuedResourcesAsyncPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.asyncio +async def test_list_valued_resources_async_from_dict(): + await test_list_valued_resources_async(request_type=dict) + + +def test_list_valued_resources_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListValuedResourcesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), "__call__" + ) as call: + call.return_value = securitycenter_service.ListValuedResourcesResponse() + client.list_valued_resources(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_valued_resources_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.ListValuedResourcesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListValuedResourcesResponse() + ) + await client.list_valued_resources(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_valued_resources_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListValuedResourcesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_valued_resources( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_valued_resources_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_valued_resources( + securitycenter_service.ListValuedResourcesRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_valued_resources_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = securitycenter_service.ListValuedResourcesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + securitycenter_service.ListValuedResourcesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_valued_resources( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_valued_resources_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_valued_resources( + securitycenter_service.ListValuedResourcesRequest(), + parent="parent_value", + ) + + +def test_list_valued_resources_pager(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + ], + next_page_token="abc", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[], + next_page_token="def", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_valued_resources(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, valued_resource.ValuedResource) for i in results) + + +def test_list_valued_resources_pages(transport_name: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + ], + next_page_token="abc", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[], + next_page_token="def", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + ], + ), + RuntimeError, + ) + pages = list(client.list_valued_resources(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_valued_resources_async_pager(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + ], + next_page_token="abc", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[], + next_page_token="def", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_valued_resources( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, valued_resource.ValuedResource) for i in responses) + + +@pytest.mark.asyncio +async def test_list_valued_resources_async_pages(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_valued_resources), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + ], + next_page_token="abc", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[], + next_page_token="def", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_valued_resources(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.SetFindingStateRequest, + dict, + ], +) +def test_set_finding_state(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_finding_state), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=finding.Finding.Severity.CRITICAL, + mute=finding.Finding.Mute.MUTED, + finding_class=finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + response = client.set_finding_state(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.SetFindingStateRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == finding.Finding.Severity.CRITICAL + assert response.mute == finding.Finding.Mute.MUTED + assert response.finding_class == finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +def test_set_finding_state_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_finding_state), "__call__" + ) as call: + client.set_finding_state() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.SetFindingStateRequest() + + +@pytest.mark.asyncio +async def test_set_finding_state_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.SetFindingStateRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_finding_state), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=finding.Finding.Severity.CRITICAL, + mute=finding.Finding.Mute.MUTED, + finding_class=finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + ) + response = await client.set_finding_state(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.SetFindingStateRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == finding.Finding.Severity.CRITICAL + assert response.mute == finding.Finding.Mute.MUTED + assert response.finding_class == finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +@pytest.mark.asyncio +async def test_set_finding_state_async_from_dict(): + await test_set_finding_state_async(request_type=dict) + + +def test_set_finding_state_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.SetFindingStateRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_finding_state), "__call__" + ) as call: + call.return_value = finding.Finding() + client.set_finding_state(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_set_finding_state_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.SetFindingStateRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_finding_state), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(finding.Finding()) + await client.set_finding_state(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_set_finding_state_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_finding_state), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = finding.Finding() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.set_finding_state( + name="name_value", + state=finding.Finding.State.ACTIVE, + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].state + mock_val = finding.Finding.State.ACTIVE + assert arg == mock_val + + +def test_set_finding_state_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.set_finding_state( + securitycenter_service.SetFindingStateRequest(), + name="name_value", + state=finding.Finding.State.ACTIVE, + ) + + +@pytest.mark.asyncio +async def test_set_finding_state_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_finding_state), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = finding.Finding() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(finding.Finding()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.set_finding_state( + name="name_value", + state=finding.Finding.State.ACTIVE, + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].state + mock_val = finding.Finding.State.ACTIVE + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_set_finding_state_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.set_finding_state( + securitycenter_service.SetFindingStateRequest(), + name="name_value", + state=finding.Finding.State.ACTIVE, + ) + + +@pytest.mark.parametrize( + "request_type", + [ + iam_policy_pb2.SetIamPolicyRequest, + dict, + ], +) +def test_set_iam_policy(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # 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: + # Designate an appropriate return value for the call. + call.return_value = policy_pb2.Policy( + version=774, + etag=b"etag_blob", + ) + response = client.set_iam_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == iam_policy_pb2.SetIamPolicyRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, policy_pb2.Policy) + assert response.version == 774 + assert response.etag == b"etag_blob" + + +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 = SecurityCenterClient( + credentials=ga_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_pb2.SetIamPolicyRequest() + + +@pytest.mark.asyncio +async def test_set_iam_policy_async( + transport: str = "grpc_asyncio", request_type=iam_policy_pb2.SetIamPolicyRequest +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # 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: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + policy_pb2.Policy( + version=774, + etag=b"etag_blob", + ) + ) + response = await client.set_iam_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == iam_policy_pb2.SetIamPolicyRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, policy_pb2.Policy) + assert response.version == 774 + assert response.etag == b"etag_blob" + + +@pytest.mark.asyncio +async def test_set_iam_policy_async_from_dict(): + await test_set_iam_policy_async(request_type=dict) + + +def test_set_iam_policy_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = iam_policy_pb2.SetIamPolicyRequest() + + request.resource = "resource_value" + + # 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: + call.return_value = policy_pb2.Policy() + client.set_iam_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "resource=resource_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_set_iam_policy_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = iam_policy_pb2.SetIamPolicyRequest() + + request.resource = "resource_value" + + # 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: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(policy_pb2.Policy()) + await client.set_iam_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "resource=resource_value", + ) in kw["metadata"] + + +def test_set_iam_policy_from_dict_foreign(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # 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: + # Designate an appropriate return value for the call. + call.return_value = policy_pb2.Policy() + response = client.set_iam_policy( + request={ + "resource": "resource_value", + "policy": policy_pb2.Policy(version=774), + "update_mask": field_mask_pb2.FieldMask(paths=["paths_value"]), + } + ) + call.assert_called() + + +def test_set_iam_policy_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # 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: + # Designate an appropriate return value for the call. + call.return_value = policy_pb2.Policy() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.set_iam_policy( + resource="resource_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val + + +def test_set_iam_policy_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.set_iam_policy( + iam_policy_pb2.SetIamPolicyRequest(), + resource="resource_value", + ) + + +@pytest.mark.asyncio +async def test_set_iam_policy_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # 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: + # Designate an appropriate return value for the call. + call.return_value = policy_pb2.Policy() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(policy_pb2.Policy()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.set_iam_policy( + resource="resource_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_set_iam_policy_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.set_iam_policy( + iam_policy_pb2.SetIamPolicyRequest(), + resource="resource_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.SetMuteRequest, + dict, + ], +) +def test_set_mute(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.set_mute), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=finding.Finding.Severity.CRITICAL, + mute=finding.Finding.Mute.MUTED, + finding_class=finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + response = client.set_mute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.SetMuteRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == finding.Finding.Severity.CRITICAL + assert response.mute == finding.Finding.Mute.MUTED + assert response.finding_class == finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +def test_set_mute_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.set_mute), "__call__") as call: + client.set_mute() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.SetMuteRequest() + + +@pytest.mark.asyncio +async def test_set_mute_async( + transport: str = "grpc_asyncio", request_type=securitycenter_service.SetMuteRequest +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.set_mute), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=finding.Finding.Severity.CRITICAL, + mute=finding.Finding.Mute.MUTED, + finding_class=finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + ) + response = await client.set_mute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.SetMuteRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == finding.Finding.Severity.CRITICAL + assert response.mute == finding.Finding.Mute.MUTED + assert response.finding_class == finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +@pytest.mark.asyncio +async def test_set_mute_async_from_dict(): + await test_set_mute_async(request_type=dict) + + +def test_set_mute_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.SetMuteRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.set_mute), "__call__") as call: + call.return_value = finding.Finding() + client.set_mute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_set_mute_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.SetMuteRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.set_mute), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(finding.Finding()) + await client.set_mute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_set_mute_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.set_mute), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = finding.Finding() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.set_mute( + name="name_value", + mute=finding.Finding.Mute.MUTED, + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].mute + mock_val = finding.Finding.Mute.MUTED + assert arg == mock_val + + +def test_set_mute_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.set_mute( + securitycenter_service.SetMuteRequest(), + name="name_value", + mute=finding.Finding.Mute.MUTED, + ) + + +@pytest.mark.asyncio +async def test_set_mute_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.set_mute), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = finding.Finding() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(finding.Finding()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.set_mute( + name="name_value", + mute=finding.Finding.Mute.MUTED, + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].mute + mock_val = finding.Finding.Mute.MUTED + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_set_mute_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.set_mute( + securitycenter_service.SetMuteRequest(), + name="name_value", + mute=finding.Finding.Mute.MUTED, + ) + + +@pytest.mark.parametrize( + "request_type", + [ + iam_policy_pb2.TestIamPermissionsRequest, + dict, + ], +) +def test_test_iam_permissions(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # 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: + # Designate an appropriate return value for the call. + call.return_value = iam_policy_pb2.TestIamPermissionsResponse( + permissions=["permissions_value"], + ) + response = client.test_iam_permissions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == iam_policy_pb2.TestIamPermissionsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, iam_policy_pb2.TestIamPermissionsResponse) + assert response.permissions == ["permissions_value"] + + +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 = SecurityCenterClient( + credentials=ga_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_pb2.TestIamPermissionsRequest() + + +@pytest.mark.asyncio +async def test_test_iam_permissions_async( + transport: str = "grpc_asyncio", + request_type=iam_policy_pb2.TestIamPermissionsRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # 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: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + iam_policy_pb2.TestIamPermissionsResponse( + permissions=["permissions_value"], + ) + ) + response = await client.test_iam_permissions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == iam_policy_pb2.TestIamPermissionsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, iam_policy_pb2.TestIamPermissionsResponse) + assert response.permissions == ["permissions_value"] + + +@pytest.mark.asyncio +async def test_test_iam_permissions_async_from_dict(): + await test_test_iam_permissions_async(request_type=dict) + + +def test_test_iam_permissions_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = iam_policy_pb2.TestIamPermissionsRequest() + + request.resource = "resource_value" + + # 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: + call.return_value = iam_policy_pb2.TestIamPermissionsResponse() + client.test_iam_permissions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "resource=resource_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_test_iam_permissions_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = iam_policy_pb2.TestIamPermissionsRequest() + + request.resource = "resource_value" + + # 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: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + iam_policy_pb2.TestIamPermissionsResponse() + ) + await client.test_iam_permissions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "resource=resource_value", + ) in kw["metadata"] + + +def test_test_iam_permissions_from_dict_foreign(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # 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: + # Designate an appropriate return value for the call. + call.return_value = iam_policy_pb2.TestIamPermissionsResponse() + response = client.test_iam_permissions( + request={ + "resource": "resource_value", + "permissions": ["permissions_value"], + } + ) + call.assert_called() + + +def test_test_iam_permissions_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # 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: + # Designate an appropriate return value for the call. + call.return_value = iam_policy_pb2.TestIamPermissionsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.test_iam_permissions( + resource="resource_value", + permissions=["permissions_value"], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val + arg = args[0].permissions + mock_val = ["permissions_value"] + assert arg == mock_val + + +def test_test_iam_permissions_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.test_iam_permissions( + iam_policy_pb2.TestIamPermissionsRequest(), + resource="resource_value", + permissions=["permissions_value"], + ) + + +@pytest.mark.asyncio +async def test_test_iam_permissions_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # 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: + # Designate an appropriate return value for the call. + call.return_value = iam_policy_pb2.TestIamPermissionsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + iam_policy_pb2.TestIamPermissionsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.test_iam_permissions( + resource="resource_value", + permissions=["permissions_value"], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val + arg = args[0].permissions + mock_val = ["permissions_value"] + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_test_iam_permissions_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.test_iam_permissions( + iam_policy_pb2.TestIamPermissionsRequest(), + resource="resource_value", + permissions=["permissions_value"], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateBigQueryExportRequest, + dict, + ], +) +def test_update_big_query_export(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = bigquery_export.BigQueryExport( + name="name_value", + description="description_value", + filter="filter_value", + dataset="dataset_value", + most_recent_editor="most_recent_editor_value", + principal="principal_value", + ) + response = client.update_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateBigQueryExportRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, bigquery_export.BigQueryExport) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.dataset == "dataset_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.principal == "principal_value" + + +def test_update_big_query_export_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_big_query_export), "__call__" + ) as call: + client.update_big_query_export() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateBigQueryExportRequest() + + +@pytest.mark.asyncio +async def test_update_big_query_export_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.UpdateBigQueryExportRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + bigquery_export.BigQueryExport( + name="name_value", + description="description_value", + filter="filter_value", + dataset="dataset_value", + most_recent_editor="most_recent_editor_value", + principal="principal_value", + ) + ) + response = await client.update_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateBigQueryExportRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, bigquery_export.BigQueryExport) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.dataset == "dataset_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.principal == "principal_value" + + +@pytest.mark.asyncio +async def test_update_big_query_export_async_from_dict(): + await test_update_big_query_export_async(request_type=dict) + + +def test_update_big_query_export_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateBigQueryExportRequest() + + request.big_query_export.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_big_query_export), "__call__" + ) as call: + call.return_value = bigquery_export.BigQueryExport() + client.update_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "big_query_export.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_big_query_export_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateBigQueryExportRequest() + + request.big_query_export.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_big_query_export), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + bigquery_export.BigQueryExport() + ) + await client.update_big_query_export(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "big_query_export.name=name_value", + ) in kw["metadata"] + + +def test_update_big_query_export_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = bigquery_export.BigQueryExport() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_big_query_export( + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].big_query_export + mock_val = bigquery_export.BigQueryExport(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_big_query_export_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_big_query_export( + securitycenter_service.UpdateBigQueryExportRequest(), + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_big_query_export_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_big_query_export), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = bigquery_export.BigQueryExport() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + bigquery_export.BigQueryExport() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_big_query_export( + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].big_query_export + mock_val = bigquery_export.BigQueryExport(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_big_query_export_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_big_query_export( + securitycenter_service.UpdateBigQueryExportRequest(), + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateExternalSystemRequest, + dict, + ], +) +def test_update_external_system(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_external_system), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_external_system.ExternalSystem( + name="name_value", + assignees=["assignees_value"], + external_uid="external_uid_value", + status="status_value", + case_uri="case_uri_value", + case_priority="case_priority_value", + ) + response = client.update_external_system(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateExternalSystemRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_external_system.ExternalSystem) + assert response.name == "name_value" + assert response.assignees == ["assignees_value"] + assert response.external_uid == "external_uid_value" + assert response.status == "status_value" + assert response.case_uri == "case_uri_value" + assert response.case_priority == "case_priority_value" + + +def test_update_external_system_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_external_system), "__call__" + ) as call: + client.update_external_system() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateExternalSystemRequest() + + +@pytest.mark.asyncio +async def test_update_external_system_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.UpdateExternalSystemRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_external_system), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_external_system.ExternalSystem( + name="name_value", + assignees=["assignees_value"], + external_uid="external_uid_value", + status="status_value", + case_uri="case_uri_value", + case_priority="case_priority_value", + ) + ) + response = await client.update_external_system(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateExternalSystemRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_external_system.ExternalSystem) + assert response.name == "name_value" + assert response.assignees == ["assignees_value"] + assert response.external_uid == "external_uid_value" + assert response.status == "status_value" + assert response.case_uri == "case_uri_value" + assert response.case_priority == "case_priority_value" + + +@pytest.mark.asyncio +async def test_update_external_system_async_from_dict(): + await test_update_external_system_async(request_type=dict) + + +def test_update_external_system_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateExternalSystemRequest() + + request.external_system.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_external_system), "__call__" + ) as call: + call.return_value = gcs_external_system.ExternalSystem() + client.update_external_system(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "external_system.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_external_system_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateExternalSystemRequest() + + request.external_system.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_external_system), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_external_system.ExternalSystem() + ) + await client.update_external_system(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "external_system.name=name_value", + ) in kw["metadata"] + + +def test_update_external_system_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_external_system), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_external_system.ExternalSystem() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_external_system( + external_system=gcs_external_system.ExternalSystem(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].external_system + mock_val = gcs_external_system.ExternalSystem(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_external_system_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_external_system( + securitycenter_service.UpdateExternalSystemRequest(), + external_system=gcs_external_system.ExternalSystem(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_external_system_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_external_system), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_external_system.ExternalSystem() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_external_system.ExternalSystem() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_external_system( + external_system=gcs_external_system.ExternalSystem(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].external_system + mock_val = gcs_external_system.ExternalSystem(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_external_system_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_external_system( + securitycenter_service.UpdateExternalSystemRequest(), + external_system=gcs_external_system.ExternalSystem(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateFindingRequest, + dict, + ], +) +def test_update_finding(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_finding), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=gcs_finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=gcs_finding.Finding.Severity.CRITICAL, + mute=gcs_finding.Finding.Mute.MUTED, + finding_class=gcs_finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + response = client.update_finding(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateFindingRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == gcs_finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == gcs_finding.Finding.Severity.CRITICAL + assert response.mute == gcs_finding.Finding.Mute.MUTED + assert response.finding_class == gcs_finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +def test_update_finding_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_finding), "__call__") as call: + client.update_finding() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateFindingRequest() + + +@pytest.mark.asyncio +async def test_update_finding_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.UpdateFindingRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_finding), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=gcs_finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=gcs_finding.Finding.Severity.CRITICAL, + mute=gcs_finding.Finding.Mute.MUTED, + finding_class=gcs_finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + ) + response = await client.update_finding(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateFindingRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == gcs_finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == gcs_finding.Finding.Severity.CRITICAL + assert response.mute == gcs_finding.Finding.Mute.MUTED + assert response.finding_class == gcs_finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +@pytest.mark.asyncio +async def test_update_finding_async_from_dict(): + await test_update_finding_async(request_type=dict) + + +def test_update_finding_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateFindingRequest() + + request.finding.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_finding), "__call__") as call: + call.return_value = gcs_finding.Finding() + client.update_finding(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "finding.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_finding_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateFindingRequest() + + request.finding.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_finding), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcs_finding.Finding()) + await client.update_finding(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "finding.name=name_value", + ) in kw["metadata"] + + +def test_update_finding_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_finding), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_finding.Finding() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_finding( + finding=gcs_finding.Finding(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].finding + mock_val = gcs_finding.Finding(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_finding_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_finding( + securitycenter_service.UpdateFindingRequest(), + finding=gcs_finding.Finding(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_finding_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_finding), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_finding.Finding() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcs_finding.Finding()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_finding( + finding=gcs_finding.Finding(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].finding + mock_val = gcs_finding.Finding(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_finding_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_finding( + securitycenter_service.UpdateFindingRequest(), + finding=gcs_finding.Finding(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateMuteConfigRequest, + dict, + ], +) +def test_update_mute_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_mute_config.MuteConfig( + name="name_value", + description="description_value", + filter="filter_value", + most_recent_editor="most_recent_editor_value", + type_=gcs_mute_config.MuteConfig.MuteConfigType.STATIC, + ) + response = client.update_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateMuteConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_mute_config.MuteConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.type_ == gcs_mute_config.MuteConfig.MuteConfigType.STATIC + + +def test_update_mute_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_mute_config), "__call__" + ) as call: + client.update_mute_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateMuteConfigRequest() + + +@pytest.mark.asyncio +async def test_update_mute_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.UpdateMuteConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_mute_config.MuteConfig( + name="name_value", + description="description_value", + filter="filter_value", + most_recent_editor="most_recent_editor_value", + type_=gcs_mute_config.MuteConfig.MuteConfigType.STATIC, + ) + ) + response = await client.update_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateMuteConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_mute_config.MuteConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.type_ == gcs_mute_config.MuteConfig.MuteConfigType.STATIC + + +@pytest.mark.asyncio +async def test_update_mute_config_async_from_dict(): + await test_update_mute_config_async(request_type=dict) + + +def test_update_mute_config_routing_parameters(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateMuteConfigRequest( + **{ + "mute_config": { + "name": "projects/sample1/locations/sample2/muteConfigs/sample3" + } + } + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_mute_config), "__call__" + ) as call: + call.return_value = gcs_mute_config.MuteConfig() + client.update_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateMuteConfigRequest( + **{ + "mute_config": { + "name": "organizations/sample1/locations/sample2/muteConfigs/sample3" + } + } + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_mute_config), "__call__" + ) as call: + call.return_value = gcs_mute_config.MuteConfig() + client.update_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateMuteConfigRequest( + **{ + "mute_config": { + "name": "folders/sample1/locations/sample2/muteConfigs/sample3" + } + } + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_mute_config), "__call__" + ) as call: + call.return_value = gcs_mute_config.MuteConfig() + client.update_mute_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + _, _, kw = call.mock_calls[0] + # This test doesn't assert anything useful. + assert kw["metadata"] + + +def test_update_mute_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_mute_config.MuteConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_mute_config( + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].mute_config + mock_val = gcs_mute_config.MuteConfig(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_mute_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_mute_config( + securitycenter_service.UpdateMuteConfigRequest(), + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_mute_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_mute_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_mute_config.MuteConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_mute_config.MuteConfig() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_mute_config( + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].mute_config + mock_val = gcs_mute_config.MuteConfig(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_mute_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_mute_config( + securitycenter_service.UpdateMuteConfigRequest(), + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateNotificationConfigRequest, + dict, + ], +) +def test_update_notification_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_notification_config.NotificationConfig( + name="name_value", + description="description_value", + pubsub_topic="pubsub_topic_value", + service_account="service_account_value", + ) + response = client.update_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateNotificationConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_notification_config.NotificationConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.pubsub_topic == "pubsub_topic_value" + assert response.service_account == "service_account_value" + + +def test_update_notification_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_notification_config), "__call__" + ) as call: + client.update_notification_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateNotificationConfigRequest() + + +@pytest.mark.asyncio +async def test_update_notification_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.UpdateNotificationConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_notification_config.NotificationConfig( + name="name_value", + description="description_value", + pubsub_topic="pubsub_topic_value", + service_account="service_account_value", + ) + ) + response = await client.update_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateNotificationConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_notification_config.NotificationConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.pubsub_topic == "pubsub_topic_value" + assert response.service_account == "service_account_value" + + +@pytest.mark.asyncio +async def test_update_notification_config_async_from_dict(): + await test_update_notification_config_async(request_type=dict) + + +def test_update_notification_config_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateNotificationConfigRequest() + + request.notification_config.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_notification_config), "__call__" + ) as call: + call.return_value = gcs_notification_config.NotificationConfig() + client.update_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "notification_config.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_notification_config_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateNotificationConfigRequest() + + request.notification_config.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_notification_config), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_notification_config.NotificationConfig() + ) + await client.update_notification_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "notification_config.name=name_value", + ) in kw["metadata"] + + +def test_update_notification_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_notification_config.NotificationConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_notification_config( + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].notification_config + mock_val = gcs_notification_config.NotificationConfig(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_notification_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_notification_config( + securitycenter_service.UpdateNotificationConfigRequest(), + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_notification_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_notification_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_notification_config.NotificationConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_notification_config.NotificationConfig() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_notification_config( + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].notification_config + mock_val = gcs_notification_config.NotificationConfig(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_notification_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_notification_config( + securitycenter_service.UpdateNotificationConfigRequest(), + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateResourceValueConfigRequest, + dict, + ], +) +def test_update_resource_value_config(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_resource_value_config.ResourceValueConfig( + name="name_value", + resource_value=gcs_resource_value_config.ResourceValue.HIGH, + tag_values=["tag_values_value"], + resource_type="resource_type_value", + scope="scope_value", + description="description_value", + ) + response = client.update_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateResourceValueConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_resource_value_config.ResourceValueConfig) + assert response.name == "name_value" + assert response.resource_value == gcs_resource_value_config.ResourceValue.HIGH + assert response.tag_values == ["tag_values_value"] + assert response.resource_type == "resource_type_value" + assert response.scope == "scope_value" + assert response.description == "description_value" + + +def test_update_resource_value_config_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_resource_value_config), "__call__" + ) as call: + client.update_resource_value_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateResourceValueConfigRequest() + + +@pytest.mark.asyncio +async def test_update_resource_value_config_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.UpdateResourceValueConfigRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_resource_value_config.ResourceValueConfig( + name="name_value", + resource_value=gcs_resource_value_config.ResourceValue.HIGH, + tag_values=["tag_values_value"], + resource_type="resource_type_value", + scope="scope_value", + description="description_value", + ) + ) + response = await client.update_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateResourceValueConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_resource_value_config.ResourceValueConfig) + assert response.name == "name_value" + assert response.resource_value == gcs_resource_value_config.ResourceValue.HIGH + assert response.tag_values == ["tag_values_value"] + assert response.resource_type == "resource_type_value" + assert response.scope == "scope_value" + assert response.description == "description_value" + + +@pytest.mark.asyncio +async def test_update_resource_value_config_async_from_dict(): + await test_update_resource_value_config_async(request_type=dict) + + +def test_update_resource_value_config_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateResourceValueConfigRequest() + + request.resource_value_config.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_resource_value_config), "__call__" + ) as call: + call.return_value = gcs_resource_value_config.ResourceValueConfig() + client.update_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "resource_value_config.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_resource_value_config_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateResourceValueConfigRequest() + + request.resource_value_config.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_resource_value_config), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_resource_value_config.ResourceValueConfig() + ) + await client.update_resource_value_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "resource_value_config.name=name_value", + ) in kw["metadata"] + + +def test_update_resource_value_config_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_resource_value_config.ResourceValueConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_resource_value_config( + resource_value_config=gcs_resource_value_config.ResourceValueConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].resource_value_config + mock_val = gcs_resource_value_config.ResourceValueConfig(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_resource_value_config_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_resource_value_config( + securitycenter_service.UpdateResourceValueConfigRequest(), + resource_value_config=gcs_resource_value_config.ResourceValueConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_resource_value_config_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_resource_value_config), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_resource_value_config.ResourceValueConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_resource_value_config.ResourceValueConfig() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_resource_value_config( + resource_value_config=gcs_resource_value_config.ResourceValueConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].resource_value_config + mock_val = gcs_resource_value_config.ResourceValueConfig(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_resource_value_config_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_resource_value_config( + securitycenter_service.UpdateResourceValueConfigRequest(), + resource_value_config=gcs_resource_value_config.ResourceValueConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateSecurityMarksRequest, + dict, + ], +) +def test_update_security_marks(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_security_marks), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_security_marks.SecurityMarks( + name="name_value", + canonical_name="canonical_name_value", + ) + response = client.update_security_marks(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateSecurityMarksRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_security_marks.SecurityMarks) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + + +def test_update_security_marks_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_security_marks), "__call__" + ) as call: + client.update_security_marks() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateSecurityMarksRequest() + + +@pytest.mark.asyncio +async def test_update_security_marks_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.UpdateSecurityMarksRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_security_marks), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_security_marks.SecurityMarks( + name="name_value", + canonical_name="canonical_name_value", + ) + ) + response = await client.update_security_marks(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateSecurityMarksRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_security_marks.SecurityMarks) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + + +@pytest.mark.asyncio +async def test_update_security_marks_async_from_dict(): + await test_update_security_marks_async(request_type=dict) + + +def test_update_security_marks_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateSecurityMarksRequest() + + request.security_marks.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_security_marks), "__call__" + ) as call: + call.return_value = gcs_security_marks.SecurityMarks() + client.update_security_marks(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "security_marks.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_security_marks_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateSecurityMarksRequest() + + request.security_marks.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_security_marks), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_security_marks.SecurityMarks() + ) + await client.update_security_marks(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "security_marks.name=name_value", + ) in kw["metadata"] + + +def test_update_security_marks_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_security_marks), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_security_marks.SecurityMarks() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_security_marks( + security_marks=gcs_security_marks.SecurityMarks(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].security_marks + mock_val = gcs_security_marks.SecurityMarks(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_security_marks_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_security_marks( + securitycenter_service.UpdateSecurityMarksRequest(), + security_marks=gcs_security_marks.SecurityMarks(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_security_marks_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_security_marks), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_security_marks.SecurityMarks() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_security_marks.SecurityMarks() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_security_marks( + security_marks=gcs_security_marks.SecurityMarks(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].security_marks + mock_val = gcs_security_marks.SecurityMarks(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_security_marks_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_security_marks( + securitycenter_service.UpdateSecurityMarksRequest(), + security_marks=gcs_security_marks.SecurityMarks(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateSourceRequest, + dict, + ], +) +def test_update_source(request_type, transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_source.Source( + name="name_value", + display_name="display_name_value", + description="description_value", + canonical_name="canonical_name_value", + ) + response = client.update_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateSourceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_source.Source) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.canonical_name == "canonical_name_value" + + +def test_update_source_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 = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_source), "__call__") as call: + client.update_source() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateSourceRequest() + + +@pytest.mark.asyncio +async def test_update_source_async( + transport: str = "grpc_asyncio", + request_type=securitycenter_service.UpdateSourceRequest, +): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcs_source.Source( + name="name_value", + display_name="display_name_value", + description="description_value", + canonical_name="canonical_name_value", + ) + ) + response = await client.update_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == securitycenter_service.UpdateSourceRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_source.Source) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.canonical_name == "canonical_name_value" + + +@pytest.mark.asyncio +async def test_update_source_async_from_dict(): + await test_update_source_async(request_type=dict) + + +def test_update_source_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateSourceRequest() + + request.source.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_source), "__call__") as call: + call.return_value = gcs_source.Source() + client.update_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "source.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_source_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = securitycenter_service.UpdateSourceRequest() + + request.source.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_source), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcs_source.Source()) + await client.update_source(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "source.name=name_value", + ) in kw["metadata"] + + +def test_update_source_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_source.Source() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_source( + source=gcs_source.Source(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].source + mock_val = gcs_source.Source(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_source_flattened_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_source( + securitycenter_service.UpdateSourceRequest(), + source=gcs_source.Source(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_source_flattened_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_source), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcs_source.Source() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcs_source.Source()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_source( + source=gcs_source.Source(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].source + mock_val = gcs_source.Source(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_source_flattened_error_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_source( + securitycenter_service.UpdateSourceRequest(), + source=gcs_source.Source(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.BatchCreateResourceValueConfigsRequest, + dict, + ], +) +def test_batch_create_resource_value_configs_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.BatchCreateResourceValueConfigsResponse() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = ( + securitycenter_service.BatchCreateResourceValueConfigsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.batch_create_resource_value_configs(request) + + # Establish that the response is the type that we expect. + assert isinstance( + response, securitycenter_service.BatchCreateResourceValueConfigsResponse + ) + + +def test_batch_create_resource_value_configs_rest_required_fields( + request_type=securitycenter_service.BatchCreateResourceValueConfigsRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_resource_value_configs._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_resource_value_configs._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.BatchCreateResourceValueConfigsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + securitycenter_service.BatchCreateResourceValueConfigsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.batch_create_resource_value_configs(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_create_resource_value_configs_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.batch_create_resource_value_configs._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_resource_value_configs_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, + "post_batch_create_resource_value_configs", + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, + "pre_batch_create_resource_value_configs", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.BatchCreateResourceValueConfigsRequest.pb( + securitycenter_service.BatchCreateResourceValueConfigsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = ( + securitycenter_service.BatchCreateResourceValueConfigsResponse.to_json( + securitycenter_service.BatchCreateResourceValueConfigsResponse() + ) + ) + + request = securitycenter_service.BatchCreateResourceValueConfigsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = ( + securitycenter_service.BatchCreateResourceValueConfigsResponse() + ) + + client.batch_create_resource_value_configs( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_create_resource_value_configs_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.BatchCreateResourceValueConfigsRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.batch_create_resource_value_configs(request) + + +def test_batch_create_resource_value_configs_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.BatchCreateResourceValueConfigsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[ + securitycenter_service.CreateResourceValueConfigRequest( + parent="parent_value" + ) + ], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = ( + securitycenter_service.BatchCreateResourceValueConfigsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.batch_create_resource_value_configs(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*}/resourceValueConfigs:batchCreate" + % client.transport._host, + args[1], + ) + + +def test_batch_create_resource_value_configs_rest_flattened_error( + transport: str = "rest", +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_resource_value_configs( + securitycenter_service.BatchCreateResourceValueConfigsRequest(), + parent="parent_value", + requests=[ + securitycenter_service.CreateResourceValueConfigRequest( + parent="parent_value" + ) + ], + ) + + +def test_batch_create_resource_value_configs_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.BulkMuteFindingsRequest, + dict, + ], +) +def test_bulk_mute_findings_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.bulk_mute_findings(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_bulk_mute_findings_rest_required_fields( + request_type=securitycenter_service.BulkMuteFindingsRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).bulk_mute_findings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).bulk_mute_findings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.bulk_mute_findings(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_bulk_mute_findings_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.bulk_mute_findings._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_bulk_mute_findings_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_bulk_mute_findings" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_bulk_mute_findings" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.BulkMuteFindingsRequest.pb( + securitycenter_service.BulkMuteFindingsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = securitycenter_service.BulkMuteFindingsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.bulk_mute_findings( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_bulk_mute_findings_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.BulkMuteFindingsRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.bulk_mute_findings(request) + + +def test_bulk_mute_findings_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.bulk_mute_findings(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*}/findings:bulkMute" % client.transport._host, + args[1], + ) + + +def test_bulk_mute_findings_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.bulk_mute_findings( + securitycenter_service.BulkMuteFindingsRequest(), + parent="parent_value", + ) + + +def test_bulk_mute_findings_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.CreateBigQueryExportRequest, + dict, + ], +) +def test_create_big_query_export_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request_init["big_query_export"] = { + "name": "name_value", + "description": "description_value", + "filter": "filter_value", + "dataset": "dataset_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "most_recent_editor": "most_recent_editor_value", + "principal": "principal_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.CreateBigQueryExportRequest.meta.fields[ + "big_query_export" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["big_query_export"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["big_query_export"][field])): + del request_init["big_query_export"][field][i][subfield] + else: + del request_init["big_query_export"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = bigquery_export.BigQueryExport( + name="name_value", + description="description_value", + filter="filter_value", + dataset="dataset_value", + most_recent_editor="most_recent_editor_value", + principal="principal_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = bigquery_export.BigQueryExport.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_big_query_export(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, bigquery_export.BigQueryExport) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.dataset == "dataset_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.principal == "principal_value" + + +def test_create_big_query_export_rest_required_fields( + request_type=securitycenter_service.CreateBigQueryExportRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["big_query_export_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "bigQueryExportId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_big_query_export._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "bigQueryExportId" in jsonified_request + assert jsonified_request["bigQueryExportId"] == request_init["big_query_export_id"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["bigQueryExportId"] = "big_query_export_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_big_query_export._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("big_query_export_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "bigQueryExportId" in jsonified_request + assert jsonified_request["bigQueryExportId"] == "big_query_export_id_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = bigquery_export.BigQueryExport() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = bigquery_export.BigQueryExport.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_big_query_export(request) + + expected_params = [ + ( + "bigQueryExportId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_big_query_export_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_big_query_export._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("bigQueryExportId",)) + & set( + ( + "parent", + "bigQueryExport", + "bigQueryExportId", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_big_query_export_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_create_big_query_export" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_create_big_query_export" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.CreateBigQueryExportRequest.pb( + securitycenter_service.CreateBigQueryExportRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = bigquery_export.BigQueryExport.to_json( + bigquery_export.BigQueryExport() + ) + + request = securitycenter_service.CreateBigQueryExportRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = bigquery_export.BigQueryExport() + + client.create_big_query_export( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_big_query_export_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.CreateBigQueryExportRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_big_query_export(request) + + +def test_create_big_query_export_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = bigquery_export.BigQueryExport() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + big_query_export_id="big_query_export_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = bigquery_export.BigQueryExport.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_big_query_export(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*/locations/*}/bigQueryExports" + % client.transport._host, + args[1], + ) + + +def test_create_big_query_export_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_big_query_export( + securitycenter_service.CreateBigQueryExportRequest(), + parent="parent_value", + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + big_query_export_id="big_query_export_id_value", + ) + + +def test_create_big_query_export_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.CreateFindingRequest, + dict, + ], +) +def test_create_finding_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/sources/sample2/locations/sample3"} + request_init["finding"] = { + "name": "name_value", + "canonical_name": "canonical_name_value", + "parent": "parent_value", + "resource_name": "resource_name_value", + "state": 1, + "category": "category_value", + "external_uri": "external_uri_value", + "source_properties": {}, + "security_marks": { + "name": "name_value", + "marks": {}, + "canonical_name": "canonical_name_value", + }, + "event_time": {"seconds": 751, "nanos": 543}, + "create_time": {}, + "severity": 1, + "mute": 1, + "finding_class": 1, + "indicator": { + "ip_addresses": ["ip_addresses_value1", "ip_addresses_value2"], + "domains": ["domains_value1", "domains_value2"], + "signatures": [ + { + "memory_hash_signature": { + "binary_family": "binary_family_value", + "detections": [ + {"binary": "binary_value", "percent_pages_matched": 0.2197} + ], + }, + "yara_rule_signature": {"yara_rule": "yara_rule_value"}, + "signature_type": 1, + } + ], + "uris": ["uris_value1", "uris_value2"], + }, + "vulnerability": { + "cve": { + "id": "id_value", + "references": [{"source": "source_value", "uri": "uri_value"}], + "cvssv3": { + "base_score": 0.1046, + "attack_vector": 1, + "attack_complexity": 1, + "privileges_required": 1, + "user_interaction": 1, + "scope": 1, + "confidentiality_impact": 1, + "integrity_impact": 1, + "availability_impact": 1, + }, + "upstream_fix_available": True, + "impact": 1, + "exploitation_activity": 1, + "observed_in_the_wild": True, + "zero_day": True, + }, + "offending_package": { + "package_name": "package_name_value", + "cpe_uri": "cpe_uri_value", + "package_type": "package_type_value", + "package_version": "package_version_value", + }, + "fixed_package": {}, + "security_bulletin": { + "bulletin_id": "bulletin_id_value", + "submission_time": {}, + "suggested_upgrade_version": "suggested_upgrade_version_value", + }, + }, + "mute_update_time": {}, + "external_systems": {}, + "mitre_attack": { + "primary_tactic": 1, + "primary_techniques": [49], + "additional_tactics": [1], + "additional_techniques": [49], + "version": "version_value", + }, + "access": { + "principal_email": "principal_email_value", + "caller_ip": "caller_ip_value", + "caller_ip_geo": {"region_code": "region_code_value"}, + "user_agent_family": "user_agent_family_value", + "user_agent": "user_agent_value", + "service_name": "service_name_value", + "method_name": "method_name_value", + "principal_subject": "principal_subject_value", + "service_account_key_name": "service_account_key_name_value", + "service_account_delegation_info": [ + { + "principal_email": "principal_email_value", + "principal_subject": "principal_subject_value", + } + ], + "user_name": "user_name_value", + }, + "connections": [ + { + "destination_ip": "destination_ip_value", + "destination_port": 1734, + "source_ip": "source_ip_value", + "source_port": 1205, + "protocol": 1, + } + ], + "mute_initiator": "mute_initiator_value", + "processes": [ + { + "name": "name_value", + "binary": { + "path": "path_value", + "size": 443, + "sha256": "sha256_value", + "hashed_size": 1159, + "partially_hashed": True, + "contents": "contents_value", + "disk_path": { + "partition_uuid": "partition_uuid_value", + "relative_path": "relative_path_value", + }, + }, + "libraries": {}, + "script": {}, + "args": ["args_value1", "args_value2"], + "arguments_truncated": True, + "env_variables": [{"name": "name_value", "val": "val_value"}], + "env_variables_truncated": True, + "pid": 317, + "parent_pid": 1062, + } + ], + "contacts": {}, + "compliances": [ + { + "standard": "standard_value", + "version": "version_value", + "ids": ["ids_value1", "ids_value2"], + } + ], + "parent_display_name": "parent_display_name_value", + "description": "description_value", + "exfiltration": { + "sources": [ + { + "name": "name_value", + "components": ["components_value1", "components_value2"], + } + ], + "targets": {}, + "total_exfiltrated_bytes": 2469, + }, + "iam_bindings": [{"action": 1, "role": "role_value", "member": "member_value"}], + "next_steps": "next_steps_value", + "module_name": "module_name_value", + "containers": [ + { + "name": "name_value", + "uri": "uri_value", + "image_id": "image_id_value", + "labels": [{"name": "name_value", "value": "value_value"}], + "create_time": {}, + } + ], + "kubernetes": { + "pods": [ + {"ns": "ns_value", "name": "name_value", "labels": {}, "containers": {}} + ], + "nodes": [{"name": "name_value"}], + "node_pools": [{"name": "name_value", "nodes": {}}], + "roles": [{"kind": 1, "ns": "ns_value", "name": "name_value"}], + "bindings": [ + { + "ns": "ns_value", + "name": "name_value", + "role": {}, + "subjects": [{"kind": 1, "ns": "ns_value", "name": "name_value"}], + } + ], + "access_reviews": [ + { + "group": "group_value", + "ns": "ns_value", + "name": "name_value", + "resource": "resource_value", + "subresource": "subresource_value", + "verb": "verb_value", + "version": "version_value", + } + ], + "objects": [ + { + "group": "group_value", + "kind": "kind_value", + "ns": "ns_value", + "name": "name_value", + "containers": {}, + } + ], + }, + "database": { + "name": "name_value", + "display_name": "display_name_value", + "user_name": "user_name_value", + "query": "query_value", + "grantees": ["grantees_value1", "grantees_value2"], + "version": "version_value", + }, + "attack_exposure": { + "score": 0.54, + "latest_calculation_time": {}, + "attack_exposure_result": "attack_exposure_result_value", + "state": 1, + "exposed_high_value_resources_count": 3637, + "exposed_medium_value_resources_count": 3862, + "exposed_low_value_resources_count": 3559, + }, + "files": {}, + "cloud_dlp_inspection": { + "inspect_job": "inspect_job_value", + "info_type": "info_type_value", + "info_type_count": 1621, + "full_scan": True, + }, + "cloud_dlp_data_profile": { + "data_profile": "data_profile_value", + "parent_type": 1, + }, + "kernel_rootkit": { + "name": "name_value", + "unexpected_code_modification": True, + "unexpected_read_only_data_modification": True, + "unexpected_ftrace_handler": True, + "unexpected_kprobe_handler": True, + "unexpected_kernel_code_pages": True, + "unexpected_system_call_handler": True, + "unexpected_interrupt_handler": True, + "unexpected_processes_in_runqueue": True, + }, + "org_policies": [{"name": "name_value"}], + "application": {"base_uri": "base_uri_value", "full_uri": "full_uri_value"}, + "backup_disaster_recovery": { + "backup_template": "backup_template_value", + "policies": ["policies_value1", "policies_value2"], + "host": "host_value", + "applications": ["applications_value1", "applications_value2"], + "storage_pool": "storage_pool_value", + "policy_options": ["policy_options_value1", "policy_options_value2"], + "profile": "profile_value", + "appliance": "appliance_value", + "backup_type": "backup_type_value", + "backup_create_time": {}, + }, + "security_posture": { + "name": "name_value", + "revision_id": "revision_id_value", + "posture_deployment_resource": "posture_deployment_resource_value", + "posture_deployment": "posture_deployment_value", + "changed_policy": "changed_policy_value", + "policy_set": "policy_set_value", + "policy": "policy_value", + "policy_drift_details": [ + { + "field": "field_value", + "expected_value": "expected_value_value", + "detected_value": "detected_value_value", + } + ], + }, + "log_entries": [ + { + "cloud_logging_entry": { + "insert_id": "insert_id_value", + "log_id": "log_id_value", + "resource_container": "resource_container_value", + "timestamp": {}, + } + } + ], + "load_balancers": [{"name": "name_value"}], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.CreateFindingRequest.meta.fields["finding"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["finding"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["finding"][field])): + del request_init["finding"][field][i][subfield] + else: + del request_init["finding"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=gcs_finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=gcs_finding.Finding.Severity.CRITICAL, + mute=gcs_finding.Finding.Mute.MUTED, + finding_class=gcs_finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_finding(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == gcs_finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == gcs_finding.Finding.Severity.CRITICAL + assert response.mute == gcs_finding.Finding.Mute.MUTED + assert response.finding_class == gcs_finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +def test_create_finding_rest_required_fields( + request_type=securitycenter_service.CreateFindingRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["finding_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "findingId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_finding._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "findingId" in jsonified_request + assert jsonified_request["findingId"] == request_init["finding_id"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["findingId"] = "finding_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_finding._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("finding_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "findingId" in jsonified_request + assert jsonified_request["findingId"] == "finding_id_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_finding.Finding() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_finding(request) + + expected_params = [ + ( + "findingId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_finding_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_finding._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("findingId",)) + & set( + ( + "parent", + "findingId", + "finding", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_finding_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_create_finding" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_create_finding" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.CreateFindingRequest.pb( + securitycenter_service.CreateFindingRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcs_finding.Finding.to_json(gcs_finding.Finding()) + + request = securitycenter_service.CreateFindingRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_finding.Finding() + + client.create_finding( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_finding_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.CreateFindingRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/sources/sample2/locations/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_finding(request) + + +def test_create_finding_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_finding.Finding() + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "organizations/sample1/sources/sample2/locations/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + finding=gcs_finding.Finding(name="name_value"), + finding_id="finding_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_finding(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*/sources/*/locations/*}/findings" + % client.transport._host, + args[1], + ) + + +def test_create_finding_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_finding( + securitycenter_service.CreateFindingRequest(), + parent="parent_value", + finding=gcs_finding.Finding(name="name_value"), + finding_id="finding_id_value", + ) + + +def test_create_finding_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.CreateMuteConfigRequest, + dict, + ], +) +def test_create_mute_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request_init["mute_config"] = { + "name": "name_value", + "description": "description_value", + "filter": "filter_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "most_recent_editor": "most_recent_editor_value", + "type_": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.CreateMuteConfigRequest.meta.fields[ + "mute_config" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["mute_config"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["mute_config"][field])): + del request_init["mute_config"][field][i][subfield] + else: + del request_init["mute_config"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_mute_config.MuteConfig( + name="name_value", + description="description_value", + filter="filter_value", + most_recent_editor="most_recent_editor_value", + type_=gcs_mute_config.MuteConfig.MuteConfigType.STATIC, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_mute_config.MuteConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_mute_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_mute_config.MuteConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.type_ == gcs_mute_config.MuteConfig.MuteConfigType.STATIC + + +def test_create_mute_config_rest_required_fields( + request_type=securitycenter_service.CreateMuteConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["mute_config_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "muteConfigId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_mute_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "muteConfigId" in jsonified_request + assert jsonified_request["muteConfigId"] == request_init["mute_config_id"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["muteConfigId"] = "mute_config_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_mute_config._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("mute_config_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "muteConfigId" in jsonified_request + assert jsonified_request["muteConfigId"] == "mute_config_id_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_mute_config.MuteConfig() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_mute_config.MuteConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_mute_config(request) + + expected_params = [ + ( + "muteConfigId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_mute_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_mute_config._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("muteConfigId",)) + & set( + ( + "parent", + "muteConfig", + "muteConfigId", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_mute_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_create_mute_config" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_create_mute_config" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.CreateMuteConfigRequest.pb( + securitycenter_service.CreateMuteConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcs_mute_config.MuteConfig.to_json( + gcs_mute_config.MuteConfig() + ) + + request = securitycenter_service.CreateMuteConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_mute_config.MuteConfig() + + client.create_mute_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_mute_config_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.CreateMuteConfigRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_mute_config(request) + + +def test_create_mute_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_mute_config.MuteConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + mute_config_id="mute_config_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_mute_config.MuteConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_mute_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*/locations/*}/muteConfigs" + % client.transport._host, + args[1], + ) + + +def test_create_mute_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_mute_config( + securitycenter_service.CreateMuteConfigRequest(), + parent="parent_value", + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + mute_config_id="mute_config_id_value", + ) + + +def test_create_mute_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.CreateNotificationConfigRequest, + dict, + ], +) +def test_create_notification_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request_init["notification_config"] = { + "name": "name_value", + "description": "description_value", + "pubsub_topic": "pubsub_topic_value", + "service_account": "service_account_value", + "streaming_config": {"filter": "filter_value"}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.CreateNotificationConfigRequest.meta.fields[ + "notification_config" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["notification_config"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["notification_config"][field])): + del request_init["notification_config"][field][i][subfield] + else: + del request_init["notification_config"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_notification_config.NotificationConfig( + name="name_value", + description="description_value", + pubsub_topic="pubsub_topic_value", + service_account="service_account_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_notification_config.NotificationConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_notification_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_notification_config.NotificationConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.pubsub_topic == "pubsub_topic_value" + assert response.service_account == "service_account_value" + + +def test_create_notification_config_rest_required_fields( + request_type=securitycenter_service.CreateNotificationConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["config_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + assert "configId" not in jsonified_request + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_notification_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "configId" in jsonified_request + assert jsonified_request["configId"] == request_init["config_id"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["configId"] = "config_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_notification_config._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("config_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "configId" in jsonified_request + assert jsonified_request["configId"] == "config_id_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_notification_config.NotificationConfig() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_notification_config.NotificationConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_notification_config(request) + + expected_params = [ + ( + "configId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_notification_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_notification_config._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("configId",)) + & set( + ( + "parent", + "configId", + "notificationConfig", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_notification_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_create_notification_config" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_create_notification_config" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.CreateNotificationConfigRequest.pb( + securitycenter_service.CreateNotificationConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcs_notification_config.NotificationConfig.to_json( + gcs_notification_config.NotificationConfig() + ) + + request = securitycenter_service.CreateNotificationConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_notification_config.NotificationConfig() + + client.create_notification_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_notification_config_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.CreateNotificationConfigRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_notification_config(request) + + +def test_create_notification_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_notification_config.NotificationConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + config_id="config_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_notification_config.NotificationConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_notification_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*/locations/*}/notificationConfigs" + % client.transport._host, + args[1], + ) + + +def test_create_notification_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_notification_config( + securitycenter_service.CreateNotificationConfigRequest(), + parent="parent_value", + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + config_id="config_id_value", + ) + + +def test_create_notification_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.CreateSourceRequest, + dict, + ], +) +def test_create_source_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request_init["source"] = { + "name": "name_value", + "display_name": "display_name_value", + "description": "description_value", + "canonical_name": "canonical_name_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.CreateSourceRequest.meta.fields["source"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["source"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["source"][field])): + del request_init["source"][field][i][subfield] + else: + del request_init["source"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_source.Source( + name="name_value", + display_name="display_name_value", + description="description_value", + canonical_name="canonical_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_source.Source.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_source(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_source.Source) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.canonical_name == "canonical_name_value" + + +def test_create_source_rest_required_fields( + request_type=securitycenter_service.CreateSourceRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_source._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_source._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_source.Source() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_source.Source.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_source(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_source_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_source._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "source", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_source_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_create_source" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_create_source" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.CreateSourceRequest.pb( + securitycenter_service.CreateSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcs_source.Source.to_json(gcs_source.Source()) + + request = securitycenter_service.CreateSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_source.Source() + + client.create_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_source_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.CreateSourceRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_source(request) + + +def test_create_source_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_source.Source() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + source=gcs_source.Source(name="name_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_source.Source.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_source(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*}/sources" % client.transport._host, args[1] + ) + + +def test_create_source_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_source( + securitycenter_service.CreateSourceRequest(), + parent="parent_value", + source=gcs_source.Source(name="name_value"), + ) + + +def test_create_source_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.DeleteBigQueryExportRequest, + dict, + ], +) +def test_delete_big_query_export_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/locations/sample2/bigQueryExports/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_big_query_export(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_big_query_export_rest_required_fields( + request_type=securitycenter_service.DeleteBigQueryExportRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_big_query_export._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_big_query_export._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_big_query_export(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_big_query_export_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_big_query_export._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_big_query_export_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_delete_big_query_export" + ) as pre: + pre.assert_not_called() + pb_message = securitycenter_service.DeleteBigQueryExportRequest.pb( + securitycenter_service.DeleteBigQueryExportRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = securitycenter_service.DeleteBigQueryExportRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_big_query_export( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_delete_big_query_export_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.DeleteBigQueryExportRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/locations/sample2/bigQueryExports/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_big_query_export(request) + + +def test_delete_big_query_export_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "organizations/sample1/locations/sample2/bigQueryExports/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_big_query_export(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/locations/*/bigQueryExports/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_big_query_export_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_big_query_export( + securitycenter_service.DeleteBigQueryExportRequest(), + name="name_value", + ) + + +def test_delete_big_query_export_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.DeleteMuteConfigRequest, + dict, + ], +) +def test_delete_mute_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/muteConfigs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_mute_config(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_mute_config_rest_required_fields( + request_type=securitycenter_service.DeleteMuteConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_mute_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_mute_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_mute_config(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_mute_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_mute_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_mute_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_delete_mute_config" + ) as pre: + pre.assert_not_called() + pb_message = securitycenter_service.DeleteMuteConfigRequest.pb( + securitycenter_service.DeleteMuteConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = securitycenter_service.DeleteMuteConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_mute_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_delete_mute_config_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.DeleteMuteConfigRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/muteConfigs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_mute_config(request) + + +def test_delete_mute_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "organizations/sample1/muteConfigs/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_mute_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/muteConfigs/*}" % client.transport._host, + args[1], + ) + + +def test_delete_mute_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_mute_config( + securitycenter_service.DeleteMuteConfigRequest(), + name="name_value", + ) + + +def test_delete_mute_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.DeleteNotificationConfigRequest, + dict, + ], +) +def test_delete_notification_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/locations/sample2/notificationConfigs/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_notification_config(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_notification_config_rest_required_fields( + request_type=securitycenter_service.DeleteNotificationConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_notification_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_notification_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_notification_config(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_notification_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_notification_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_notification_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_delete_notification_config" + ) as pre: + pre.assert_not_called() + pb_message = securitycenter_service.DeleteNotificationConfigRequest.pb( + securitycenter_service.DeleteNotificationConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = securitycenter_service.DeleteNotificationConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_notification_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_delete_notification_config_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.DeleteNotificationConfigRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/locations/sample2/notificationConfigs/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_notification_config(request) + + +def test_delete_notification_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "organizations/sample1/locations/sample2/notificationConfigs/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_notification_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/locations/*/notificationConfigs/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_notification_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_notification_config( + securitycenter_service.DeleteNotificationConfigRequest(), + name="name_value", + ) + + +def test_delete_notification_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.DeleteResourceValueConfigRequest, + dict, + ], +) +def test_delete_resource_value_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/resourceValueConfigs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_resource_value_config(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_resource_value_config_rest_required_fields( + request_type=securitycenter_service.DeleteResourceValueConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_resource_value_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_resource_value_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_resource_value_config(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_resource_value_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_resource_value_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_resource_value_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_delete_resource_value_config" + ) as pre: + pre.assert_not_called() + pb_message = securitycenter_service.DeleteResourceValueConfigRequest.pb( + securitycenter_service.DeleteResourceValueConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = securitycenter_service.DeleteResourceValueConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_resource_value_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_delete_resource_value_config_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.DeleteResourceValueConfigRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/resourceValueConfigs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_resource_value_config(request) + + +def test_delete_resource_value_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "organizations/sample1/resourceValueConfigs/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_resource_value_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/resourceValueConfigs/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_resource_value_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_resource_value_config( + securitycenter_service.DeleteResourceValueConfigRequest(), + name="name_value", + ) + + +def test_delete_resource_value_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetBigQueryExportRequest, + dict, + ], +) +def test_get_big_query_export_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/locations/sample2/bigQueryExports/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = bigquery_export.BigQueryExport( + name="name_value", + description="description_value", + filter="filter_value", + dataset="dataset_value", + most_recent_editor="most_recent_editor_value", + principal="principal_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = bigquery_export.BigQueryExport.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_big_query_export(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, bigquery_export.BigQueryExport) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.dataset == "dataset_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.principal == "principal_value" + + +def test_get_big_query_export_rest_required_fields( + request_type=securitycenter_service.GetBigQueryExportRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_big_query_export._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_big_query_export._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = bigquery_export.BigQueryExport() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = bigquery_export.BigQueryExport.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_big_query_export(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_big_query_export_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_big_query_export._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_big_query_export_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_get_big_query_export" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_get_big_query_export" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.GetBigQueryExportRequest.pb( + securitycenter_service.GetBigQueryExportRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = bigquery_export.BigQueryExport.to_json( + bigquery_export.BigQueryExport() + ) + + request = securitycenter_service.GetBigQueryExportRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = bigquery_export.BigQueryExport() + + client.get_big_query_export( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_big_query_export_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.GetBigQueryExportRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/locations/sample2/bigQueryExports/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_big_query_export(request) + + +def test_get_big_query_export_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = bigquery_export.BigQueryExport() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "organizations/sample1/locations/sample2/bigQueryExports/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = bigquery_export.BigQueryExport.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_big_query_export(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/locations/*/bigQueryExports/*}" + % client.transport._host, + args[1], + ) + + +def test_get_big_query_export_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_big_query_export( + securitycenter_service.GetBigQueryExportRequest(), + name="name_value", + ) + + +def test_get_big_query_export_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetSimulationRequest, + dict, + ], +) +def test_get_simulation_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/simulations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = simulation.Simulation( + name="name_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = simulation.Simulation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_simulation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, simulation.Simulation) + assert response.name == "name_value" + + +def test_get_simulation_rest_required_fields( + request_type=securitycenter_service.GetSimulationRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_simulation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_simulation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = simulation.Simulation() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = simulation.Simulation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_simulation(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_simulation_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_simulation._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_simulation_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_get_simulation" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_get_simulation" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.GetSimulationRequest.pb( + securitycenter_service.GetSimulationRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = simulation.Simulation.to_json( + simulation.Simulation() + ) + + request = securitycenter_service.GetSimulationRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = simulation.Simulation() + + client.get_simulation( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_simulation_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.GetSimulationRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/simulations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_simulation(request) + + +def test_get_simulation_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = simulation.Simulation() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "organizations/sample1/simulations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = simulation.Simulation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_simulation(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/simulations/*}" % client.transport._host, + args[1], + ) + + +def test_get_simulation_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_simulation( + securitycenter_service.GetSimulationRequest(), + name="name_value", + ) + + +def test_get_simulation_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetValuedResourceRequest, + dict, + ], +) +def test_get_valued_resource_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/simulations/sample2/valuedResources/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = valued_resource.ValuedResource( + name="name_value", + resource="resource_value", + resource_type="resource_type_value", + display_name="display_name_value", + resource_value=valued_resource.ValuedResource.ResourceValue.RESOURCE_VALUE_LOW, + exposed_score=0.1395, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = valued_resource.ValuedResource.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_valued_resource(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, valued_resource.ValuedResource) + assert response.name == "name_value" + assert response.resource == "resource_value" + assert response.resource_type == "resource_type_value" + assert response.display_name == "display_name_value" + assert ( + response.resource_value + == valued_resource.ValuedResource.ResourceValue.RESOURCE_VALUE_LOW + ) + assert math.isclose(response.exposed_score, 0.1395, rel_tol=1e-6) + + +def test_get_valued_resource_rest_required_fields( + request_type=securitycenter_service.GetValuedResourceRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_valued_resource._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_valued_resource._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = valued_resource.ValuedResource() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = valued_resource.ValuedResource.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_valued_resource(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_valued_resource_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_valued_resource._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_valued_resource_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_get_valued_resource" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_get_valued_resource" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.GetValuedResourceRequest.pb( + securitycenter_service.GetValuedResourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = valued_resource.ValuedResource.to_json( + valued_resource.ValuedResource() + ) + + request = securitycenter_service.GetValuedResourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = valued_resource.ValuedResource() + + client.get_valued_resource( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_valued_resource_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.GetValuedResourceRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/simulations/sample2/valuedResources/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_valued_resource(request) + + +def test_get_valued_resource_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = valued_resource.ValuedResource() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "organizations/sample1/simulations/sample2/valuedResources/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = valued_resource.ValuedResource.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_valued_resource(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/simulations/*/valuedResources/*}" + % client.transport._host, + args[1], + ) + + +def test_get_valued_resource_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_valued_resource( + securitycenter_service.GetValuedResourceRequest(), + name="name_value", + ) + + +def test_get_valued_resource_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + iam_policy_pb2.GetIamPolicyRequest, + dict, + ], +) +def test_get_iam_policy_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = policy_pb2.Policy( + version=774, + etag=b"etag_blob", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_iam_policy(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, policy_pb2.Policy) + assert response.version == 774 + assert response.etag == b"etag_blob" + + +def test_get_iam_policy_rest_required_fields( + request_type=iam_policy_pb2.GetIamPolicyRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["resource"] = "" + request = request_type(**request_init) + pb_request = request + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_iam_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["resource"] = "resource_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_iam_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "resource" in jsonified_request + assert jsonified_request["resource"] == "resource_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = policy_pb2.Policy() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_iam_policy(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_iam_policy_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_iam_policy._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("resource",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_iam_policy_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_get_iam_policy" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_get_iam_policy" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = iam_policy_pb2.GetIamPolicyRequest() + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(policy_pb2.Policy()) + + request = iam_policy_pb2.GetIamPolicyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = policy_pb2.Policy() + + client.get_iam_policy( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_iam_policy_rest_bad_request( + transport: str = "rest", request_type=iam_policy_pb2.GetIamPolicyRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_iam_policy(request) + + +def test_get_iam_policy_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = policy_pb2.Policy() + + # get arguments that satisfy an http rule for this method + sample_request = {"resource": "organizations/sample1/sources/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + resource="resource_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_iam_policy(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{resource=organizations/*/sources/*}:getIamPolicy" + % client.transport._host, + args[1], + ) + + +def test_get_iam_policy_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_iam_policy( + iam_policy_pb2.GetIamPolicyRequest(), + resource="resource_value", + ) + + +def test_get_iam_policy_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetMuteConfigRequest, + dict, + ], +) +def test_get_mute_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/muteConfigs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mute_config.MuteConfig( + name="name_value", + description="description_value", + filter="filter_value", + most_recent_editor="most_recent_editor_value", + type_=mute_config.MuteConfig.MuteConfigType.STATIC, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = mute_config.MuteConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_mute_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, mute_config.MuteConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.type_ == mute_config.MuteConfig.MuteConfigType.STATIC + + +def test_get_mute_config_rest_required_fields( + request_type=securitycenter_service.GetMuteConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_mute_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_mute_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = mute_config.MuteConfig() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mute_config.MuteConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_mute_config(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_mute_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_mute_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_mute_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_get_mute_config" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_get_mute_config" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.GetMuteConfigRequest.pb( + securitycenter_service.GetMuteConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = mute_config.MuteConfig.to_json( + mute_config.MuteConfig() + ) + + request = securitycenter_service.GetMuteConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = mute_config.MuteConfig() + + client.get_mute_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_mute_config_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.GetMuteConfigRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/muteConfigs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_mute_config(request) + + +def test_get_mute_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mute_config.MuteConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "organizations/sample1/muteConfigs/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = mute_config.MuteConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_mute_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/muteConfigs/*}" % client.transport._host, + args[1], + ) + + +def test_get_mute_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_mute_config( + securitycenter_service.GetMuteConfigRequest(), + name="name_value", + ) + + +def test_get_mute_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetNotificationConfigRequest, + dict, + ], +) +def test_get_notification_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/locations/sample2/notificationConfigs/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = notification_config.NotificationConfig( + name="name_value", + description="description_value", + pubsub_topic="pubsub_topic_value", + service_account="service_account_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = notification_config.NotificationConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_notification_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, notification_config.NotificationConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.pubsub_topic == "pubsub_topic_value" + assert response.service_account == "service_account_value" + + +def test_get_notification_config_rest_required_fields( + request_type=securitycenter_service.GetNotificationConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_notification_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_notification_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = notification_config.NotificationConfig() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = notification_config.NotificationConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_notification_config(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_notification_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_notification_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_notification_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_get_notification_config" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_get_notification_config" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.GetNotificationConfigRequest.pb( + securitycenter_service.GetNotificationConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = notification_config.NotificationConfig.to_json( + notification_config.NotificationConfig() + ) + + request = securitycenter_service.GetNotificationConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = notification_config.NotificationConfig() + + client.get_notification_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_notification_config_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.GetNotificationConfigRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/locations/sample2/notificationConfigs/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_notification_config(request) + + +def test_get_notification_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = notification_config.NotificationConfig() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "organizations/sample1/locations/sample2/notificationConfigs/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = notification_config.NotificationConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_notification_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/locations/*/notificationConfigs/*}" + % client.transport._host, + args[1], + ) + + +def test_get_notification_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_notification_config( + securitycenter_service.GetNotificationConfigRequest(), + name="name_value", + ) + + +def test_get_notification_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetResourceValueConfigRequest, + dict, + ], +) +def test_get_resource_value_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/resourceValueConfigs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = resource_value_config.ResourceValueConfig( + name="name_value", + resource_value=resource_value_config.ResourceValue.HIGH, + tag_values=["tag_values_value"], + resource_type="resource_type_value", + scope="scope_value", + description="description_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = resource_value_config.ResourceValueConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_resource_value_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, resource_value_config.ResourceValueConfig) + assert response.name == "name_value" + assert response.resource_value == resource_value_config.ResourceValue.HIGH + assert response.tag_values == ["tag_values_value"] + assert response.resource_type == "resource_type_value" + assert response.scope == "scope_value" + assert response.description == "description_value" + + +def test_get_resource_value_config_rest_required_fields( + request_type=securitycenter_service.GetResourceValueConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_resource_value_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_resource_value_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = resource_value_config.ResourceValueConfig() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = resource_value_config.ResourceValueConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_resource_value_config(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_resource_value_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_resource_value_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_resource_value_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_get_resource_value_config" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_get_resource_value_config" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.GetResourceValueConfigRequest.pb( + securitycenter_service.GetResourceValueConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = resource_value_config.ResourceValueConfig.to_json( + resource_value_config.ResourceValueConfig() + ) + + request = securitycenter_service.GetResourceValueConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = resource_value_config.ResourceValueConfig() + + client.get_resource_value_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_resource_value_config_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.GetResourceValueConfigRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/resourceValueConfigs/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_resource_value_config(request) + + +def test_get_resource_value_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = resource_value_config.ResourceValueConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "organizations/sample1/resourceValueConfigs/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = resource_value_config.ResourceValueConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_resource_value_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/resourceValueConfigs/*}" + % client.transport._host, + args[1], + ) + + +def test_get_resource_value_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_resource_value_config( + securitycenter_service.GetResourceValueConfigRequest(), + name="name_value", + ) + + +def test_get_resource_value_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GetSourceRequest, + dict, + ], +) +def test_get_source_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = source.Source( + name="name_value", + display_name="display_name_value", + description="description_value", + canonical_name="canonical_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = source.Source.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_source(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, source.Source) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.canonical_name == "canonical_name_value" + + +def test_get_source_rest_required_fields( + request_type=securitycenter_service.GetSourceRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_source._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_source._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = source.Source() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = source.Source.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_source(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_source_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_source._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_source_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_get_source" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_get_source" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.GetSourceRequest.pb( + securitycenter_service.GetSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = source.Source.to_json(source.Source()) + + request = securitycenter_service.GetSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = source.Source() + + client.get_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_source_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.GetSourceRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_source(request) + + +def test_get_source_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = source.Source() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "organizations/sample1/sources/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = source.Source.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_source(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/sources/*}" % client.transport._host, args[1] + ) + + +def test_get_source_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_source( + securitycenter_service.GetSourceRequest(), + name="name_value", + ) + + +def test_get_source_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.GroupFindingsRequest, + dict, + ], +) +def test_group_findings_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.GroupFindingsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.GroupFindingsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.group_findings(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.GroupFindingsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +def test_group_findings_rest_required_fields( + request_type=securitycenter_service.GroupFindingsRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["group_by"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).group_findings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["groupBy"] = "group_by_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).group_findings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "groupBy" in jsonified_request + assert jsonified_request["groupBy"] == "group_by_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.GroupFindingsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = securitycenter_service.GroupFindingsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.group_findings(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_group_findings_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.group_findings._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "groupBy", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_group_findings_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_group_findings" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_group_findings" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.GroupFindingsRequest.pb( + securitycenter_service.GroupFindingsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = ( + securitycenter_service.GroupFindingsResponse.to_json( + securitycenter_service.GroupFindingsResponse() + ) + ) + + request = securitycenter_service.GroupFindingsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = securitycenter_service.GroupFindingsResponse() + + client.group_findings( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_group_findings_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.GroupFindingsRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.group_findings(request) + + +def test_group_findings_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.GroupFindingsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/sources/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + group_by="group_by_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.GroupFindingsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.group_findings(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*/sources/*}/findings:group" + % client.transport._host, + args[1], + ) + + +def test_group_findings_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.group_findings( + securitycenter_service.GroupFindingsRequest(), + parent="parent_value", + group_by="group_by_value", + ) + + +def test_group_findings_rest_pager(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + ], + next_page_token="abc", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[], + next_page_token="def", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + ], + next_page_token="ghi", + ), + securitycenter_service.GroupFindingsResponse( + group_by_results=[ + securitycenter_service.GroupResult(), + securitycenter_service.GroupResult(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + securitycenter_service.GroupFindingsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "organizations/sample1/sources/sample2"} + + pager = client.group_findings(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, securitycenter_service.GroupResult) for i in results) + + pages = list(client.group_findings(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListAttackPathsRequest, + dict, + ], +) +def test_list_attack_paths_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/simulations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListAttackPathsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListAttackPathsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_attack_paths(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAttackPathsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_attack_paths_rest_required_fields( + request_type=securitycenter_service.ListAttackPathsRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_attack_paths._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_attack_paths._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListAttackPathsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = securitycenter_service.ListAttackPathsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_attack_paths(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_attack_paths_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_attack_paths._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_attack_paths_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_list_attack_paths" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_list_attack_paths" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.ListAttackPathsRequest.pb( + securitycenter_service.ListAttackPathsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = ( + securitycenter_service.ListAttackPathsResponse.to_json( + securitycenter_service.ListAttackPathsResponse() + ) + ) + + request = securitycenter_service.ListAttackPathsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = securitycenter_service.ListAttackPathsResponse() + + client.list_attack_paths( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_attack_paths_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.ListAttackPathsRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/simulations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_attack_paths(request) + + +def test_list_attack_paths_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListAttackPathsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/simulations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListAttackPathsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_attack_paths(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*/simulations/*}/attackPaths" + % client.transport._host, + args[1], + ) + + +def test_list_attack_paths_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_attack_paths( + securitycenter_service.ListAttackPathsRequest(), + parent="parent_value", + ) + + +def test_list_attack_paths_rest_pager(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + attack_path.AttackPath(), + attack_path.AttackPath(), + ], + next_page_token="abc", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[], + next_page_token="def", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListAttackPathsResponse( + attack_paths=[ + attack_path.AttackPath(), + attack_path.AttackPath(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + securitycenter_service.ListAttackPathsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "organizations/sample1/simulations/sample2"} + + pager = client.list_attack_paths(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, attack_path.AttackPath) for i in results) + + pages = list(client.list_attack_paths(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListBigQueryExportsRequest, + dict, + ], +) +def test_list_big_query_exports_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListBigQueryExportsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListBigQueryExportsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_big_query_exports(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListBigQueryExportsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_big_query_exports_rest_required_fields( + request_type=securitycenter_service.ListBigQueryExportsRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_big_query_exports._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_big_query_exports._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListBigQueryExportsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = securitycenter_service.ListBigQueryExportsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_big_query_exports(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_big_query_exports_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_big_query_exports._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_big_query_exports_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_list_big_query_exports" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_list_big_query_exports" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.ListBigQueryExportsRequest.pb( + securitycenter_service.ListBigQueryExportsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = ( + securitycenter_service.ListBigQueryExportsResponse.to_json( + securitycenter_service.ListBigQueryExportsResponse() + ) + ) + + request = securitycenter_service.ListBigQueryExportsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = securitycenter_service.ListBigQueryExportsResponse() + + client.list_big_query_exports( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_big_query_exports_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.ListBigQueryExportsRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_big_query_exports(request) + + +def test_list_big_query_exports_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListBigQueryExportsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListBigQueryExportsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_big_query_exports(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*/locations/*}/bigQueryExports" + % client.transport._host, + args[1], + ) + + +def test_list_big_query_exports_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_big_query_exports( + securitycenter_service.ListBigQueryExportsRequest(), + parent="parent_value", + ) + + +def test_list_big_query_exports_rest_pager(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + ], + next_page_token="abc", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[], + next_page_token="def", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListBigQueryExportsResponse( + big_query_exports=[ + bigquery_export.BigQueryExport(), + bigquery_export.BigQueryExport(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + securitycenter_service.ListBigQueryExportsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "organizations/sample1/locations/sample2"} + + pager = client.list_big_query_exports(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, bigquery_export.BigQueryExport) for i in results) + + pages = list(client.list_big_query_exports(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListFindingsRequest, + dict, + ], +) +def test_list_findings_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListFindingsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListFindingsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_findings(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListFindingsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +def test_list_findings_rest_required_fields( + request_type=securitycenter_service.ListFindingsRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_findings._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_findings._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "field_mask", + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListFindingsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = securitycenter_service.ListFindingsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_findings(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_findings_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_findings._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "fieldMask", + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_findings_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_list_findings" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_list_findings" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.ListFindingsRequest.pb( + securitycenter_service.ListFindingsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = securitycenter_service.ListFindingsResponse.to_json( + securitycenter_service.ListFindingsResponse() + ) + + request = securitycenter_service.ListFindingsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = securitycenter_service.ListFindingsResponse() + + client.list_findings( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_findings_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.ListFindingsRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_findings(request) + + +def test_list_findings_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListFindingsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/sources/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListFindingsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_findings(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*/sources/*}/findings" + % client.transport._host, + args[1], + ) + + +def test_list_findings_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_findings( + securitycenter_service.ListFindingsRequest(), + parent="parent_value", + ) + + +def test_list_findings_rest_pager(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + next_page_token="abc", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[], + next_page_token="def", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListFindingsResponse( + list_findings_results=[ + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + securitycenter_service.ListFindingsResponse.ListFindingsResult(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + securitycenter_service.ListFindingsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "organizations/sample1/sources/sample2"} + + pager = client.list_findings(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance( + i, securitycenter_service.ListFindingsResponse.ListFindingsResult + ) + for i in results + ) + + pages = list(client.list_findings(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListMuteConfigsRequest, + dict, + ], +) +def test_list_mute_configs_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListMuteConfigsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListMuteConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_mute_configs(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListMuteConfigsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_mute_configs_rest_required_fields( + request_type=securitycenter_service.ListMuteConfigsRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_mute_configs._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_mute_configs._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListMuteConfigsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = securitycenter_service.ListMuteConfigsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_mute_configs(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_mute_configs_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_mute_configs._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_mute_configs_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_list_mute_configs" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_list_mute_configs" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.ListMuteConfigsRequest.pb( + securitycenter_service.ListMuteConfigsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = ( + securitycenter_service.ListMuteConfigsResponse.to_json( + securitycenter_service.ListMuteConfigsResponse() + ) + ) + + request = securitycenter_service.ListMuteConfigsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = securitycenter_service.ListMuteConfigsResponse() + + client.list_mute_configs( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_mute_configs_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.ListMuteConfigsRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_mute_configs(request) + + +def test_list_mute_configs_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListMuteConfigsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListMuteConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_mute_configs(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*}/muteConfigs" % client.transport._host, + args[1], + ) + + +def test_list_mute_configs_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_mute_configs( + securitycenter_service.ListMuteConfigsRequest(), + parent="parent_value", + ) + + +def test_list_mute_configs_rest_pager(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + mute_config.MuteConfig(), + mute_config.MuteConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[], + next_page_token="def", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListMuteConfigsResponse( + mute_configs=[ + mute_config.MuteConfig(), + mute_config.MuteConfig(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + securitycenter_service.ListMuteConfigsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "organizations/sample1"} + + pager = client.list_mute_configs(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, mute_config.MuteConfig) for i in results) + + pages = list(client.list_mute_configs(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListNotificationConfigsRequest, + dict, + ], +) +def test_list_notification_configs_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListNotificationConfigsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListNotificationConfigsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_notification_configs(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNotificationConfigsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_notification_configs_rest_required_fields( + request_type=securitycenter_service.ListNotificationConfigsRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_notification_configs._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_notification_configs._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListNotificationConfigsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = securitycenter_service.ListNotificationConfigsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_notification_configs(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_notification_configs_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_notification_configs._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_notification_configs_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_list_notification_configs" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_list_notification_configs" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.ListNotificationConfigsRequest.pb( + securitycenter_service.ListNotificationConfigsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = ( + securitycenter_service.ListNotificationConfigsResponse.to_json( + securitycenter_service.ListNotificationConfigsResponse() + ) + ) + + request = securitycenter_service.ListNotificationConfigsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = securitycenter_service.ListNotificationConfigsResponse() + + client.list_notification_configs( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_notification_configs_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.ListNotificationConfigsRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_notification_configs(request) + + +def test_list_notification_configs_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListNotificationConfigsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListNotificationConfigsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_notification_configs(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*/locations/*}/notificationConfigs" + % client.transport._host, + args[1], + ) + + +def test_list_notification_configs_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_notification_configs( + securitycenter_service.ListNotificationConfigsRequest(), + parent="parent_value", + ) + + +def test_list_notification_configs_rest_pager(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[], + next_page_token="def", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListNotificationConfigsResponse( + notification_configs=[ + notification_config.NotificationConfig(), + notification_config.NotificationConfig(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + securitycenter_service.ListNotificationConfigsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "organizations/sample1/locations/sample2"} + + pager = client.list_notification_configs(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, notification_config.NotificationConfig) for i in results + ) + + pages = list(client.list_notification_configs(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListResourceValueConfigsRequest, + dict, + ], +) +def test_list_resource_value_configs_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListResourceValueConfigsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListResourceValueConfigsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_resource_value_configs(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListResourceValueConfigsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_resource_value_configs_rest_required_fields( + request_type=securitycenter_service.ListResourceValueConfigsRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_resource_value_configs._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_resource_value_configs._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListResourceValueConfigsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = securitycenter_service.ListResourceValueConfigsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_resource_value_configs(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_resource_value_configs_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_resource_value_configs._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_resource_value_configs_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_list_resource_value_configs" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_list_resource_value_configs" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.ListResourceValueConfigsRequest.pb( + securitycenter_service.ListResourceValueConfigsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = ( + securitycenter_service.ListResourceValueConfigsResponse.to_json( + securitycenter_service.ListResourceValueConfigsResponse() + ) + ) + + request = securitycenter_service.ListResourceValueConfigsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = securitycenter_service.ListResourceValueConfigsResponse() + + client.list_resource_value_configs( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_resource_value_configs_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.ListResourceValueConfigsRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_resource_value_configs(request) + + +def test_list_resource_value_configs_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListResourceValueConfigsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListResourceValueConfigsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_resource_value_configs(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*}/resourceValueConfigs" + % client.transport._host, + args[1], + ) + + +def test_list_resource_value_configs_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_resource_value_configs( + securitycenter_service.ListResourceValueConfigsRequest(), + parent="parent_value", + ) + + +def test_list_resource_value_configs_rest_pager(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + ], + next_page_token="abc", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[], + next_page_token="def", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListResourceValueConfigsResponse( + resource_value_configs=[ + resource_value_config.ResourceValueConfig(), + resource_value_config.ResourceValueConfig(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + securitycenter_service.ListResourceValueConfigsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "organizations/sample1"} + + pager = client.list_resource_value_configs(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, resource_value_config.ResourceValueConfig) for i in results + ) + + pages = list(client.list_resource_value_configs(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListSourcesRequest, + dict, + ], +) +def test_list_sources_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListSourcesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListSourcesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_sources(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSourcesPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_sources_rest_required_fields( + request_type=securitycenter_service.ListSourcesRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_sources._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_sources._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListSourcesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = securitycenter_service.ListSourcesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_sources(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_sources_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_sources._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_sources_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_list_sources" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_list_sources" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.ListSourcesRequest.pb( + securitycenter_service.ListSourcesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = securitycenter_service.ListSourcesResponse.to_json( + securitycenter_service.ListSourcesResponse() + ) + + request = securitycenter_service.ListSourcesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = securitycenter_service.ListSourcesResponse() + + client.list_sources( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_sources_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.ListSourcesRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_sources(request) + + +def test_list_sources_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListSourcesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListSourcesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_sources(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*}/sources" % client.transport._host, args[1] + ) + + +def test_list_sources_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_sources( + securitycenter_service.ListSourcesRequest(), + parent="parent_value", + ) + + +def test_list_sources_rest_pager(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + source.Source(), + source.Source(), + ], + next_page_token="abc", + ), + securitycenter_service.ListSourcesResponse( + sources=[], + next_page_token="def", + ), + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListSourcesResponse( + sources=[ + source.Source(), + source.Source(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + securitycenter_service.ListSourcesResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "organizations/sample1"} + + pager = client.list_sources(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, source.Source) for i in results) + + pages = list(client.list_sources(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.ListValuedResourcesRequest, + dict, + ], +) +def test_list_valued_resources_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/simulations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListValuedResourcesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListValuedResourcesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_valued_resources(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListValuedResourcesPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +def test_list_valued_resources_rest_required_fields( + request_type=securitycenter_service.ListValuedResourcesRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_valued_resources._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_valued_resources._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListValuedResourcesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = securitycenter_service.ListValuedResourcesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_valued_resources(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_valued_resources_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_valued_resources._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_valued_resources_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_list_valued_resources" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_list_valued_resources" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.ListValuedResourcesRequest.pb( + securitycenter_service.ListValuedResourcesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = ( + securitycenter_service.ListValuedResourcesResponse.to_json( + securitycenter_service.ListValuedResourcesResponse() + ) + ) + + request = securitycenter_service.ListValuedResourcesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = securitycenter_service.ListValuedResourcesResponse() + + client.list_valued_resources( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_valued_resources_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.ListValuedResourcesRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/simulations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_valued_resources(request) + + +def test_list_valued_resources_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = securitycenter_service.ListValuedResourcesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/simulations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = securitycenter_service.ListValuedResourcesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_valued_resources(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=organizations/*/simulations/*}/valuedResources" + % client.transport._host, + args[1], + ) + + +def test_list_valued_resources_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_valued_resources( + securitycenter_service.ListValuedResourcesRequest(), + parent="parent_value", + ) + + +def test_list_valued_resources_rest_pager(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + ], + next_page_token="abc", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[], + next_page_token="def", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + ], + next_page_token="ghi", + ), + securitycenter_service.ListValuedResourcesResponse( + valued_resources=[ + valued_resource.ValuedResource(), + valued_resource.ValuedResource(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + securitycenter_service.ListValuedResourcesResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "organizations/sample1/simulations/sample2"} + + pager = client.list_valued_resources(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, valued_resource.ValuedResource) for i in results) + + pages = list(client.list_valued_resources(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.SetFindingStateRequest, + dict, + ], +) +def test_set_finding_state_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/sources/sample2/findings/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=finding.Finding.Severity.CRITICAL, + mute=finding.Finding.Mute.MUTED, + finding_class=finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.set_finding_state(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == finding.Finding.Severity.CRITICAL + assert response.mute == finding.Finding.Mute.MUTED + assert response.finding_class == finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +def test_set_finding_state_rest_required_fields( + request_type=securitycenter_service.SetFindingStateRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).set_finding_state._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).set_finding_state._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = finding.Finding() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.set_finding_state(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_set_finding_state_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.set_finding_state._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "name", + "state", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_set_finding_state_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_set_finding_state" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_set_finding_state" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.SetFindingStateRequest.pb( + securitycenter_service.SetFindingStateRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = finding.Finding.to_json(finding.Finding()) + + request = securitycenter_service.SetFindingStateRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = finding.Finding() + + client.set_finding_state( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_set_finding_state_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.SetFindingStateRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/sources/sample2/findings/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.set_finding_state(request) + + +def test_set_finding_state_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = finding.Finding() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "organizations/sample1/sources/sample2/findings/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + state=finding.Finding.State.ACTIVE, + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.set_finding_state(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/sources/*/findings/*}:setState" + % client.transport._host, + args[1], + ) + + +def test_set_finding_state_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.set_finding_state( + securitycenter_service.SetFindingStateRequest(), + name="name_value", + state=finding.Finding.State.ACTIVE, + ) + + +def test_set_finding_state_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + iam_policy_pb2.SetIamPolicyRequest, + dict, + ], +) +def test_set_iam_policy_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = policy_pb2.Policy( + version=774, + etag=b"etag_blob", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.set_iam_policy(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, policy_pb2.Policy) + assert response.version == 774 + assert response.etag == b"etag_blob" + + +def test_set_iam_policy_rest_required_fields( + request_type=iam_policy_pb2.SetIamPolicyRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["resource"] = "" + request = request_type(**request_init) + pb_request = request + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).set_iam_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["resource"] = "resource_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).set_iam_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "resource" in jsonified_request + assert jsonified_request["resource"] == "resource_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = policy_pb2.Policy() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.set_iam_policy(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_set_iam_policy_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.set_iam_policy._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "resource", + "policy", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_set_iam_policy_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_set_iam_policy" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_set_iam_policy" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = iam_policy_pb2.SetIamPolicyRequest() + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(policy_pb2.Policy()) + + request = iam_policy_pb2.SetIamPolicyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = policy_pb2.Policy() + + client.set_iam_policy( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_set_iam_policy_rest_bad_request( + transport: str = "rest", request_type=iam_policy_pb2.SetIamPolicyRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.set_iam_policy(request) + + +def test_set_iam_policy_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = policy_pb2.Policy() + + # get arguments that satisfy an http rule for this method + sample_request = {"resource": "organizations/sample1/sources/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + resource="resource_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.set_iam_policy(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{resource=organizations/*/sources/*}:setIamPolicy" + % client.transport._host, + args[1], + ) + + +def test_set_iam_policy_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.set_iam_policy( + iam_policy_pb2.SetIamPolicyRequest(), + resource="resource_value", + ) + + +def test_set_iam_policy_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.SetMuteRequest, + dict, + ], +) +def test_set_mute_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/sources/sample2/findings/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=finding.Finding.Severity.CRITICAL, + mute=finding.Finding.Mute.MUTED, + finding_class=finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.set_mute(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == finding.Finding.Severity.CRITICAL + assert response.mute == finding.Finding.Mute.MUTED + assert response.finding_class == finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +def test_set_mute_rest_required_fields( + request_type=securitycenter_service.SetMuteRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).set_mute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).set_mute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = finding.Finding() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.set_mute(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_set_mute_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.set_mute._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "name", + "mute", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_set_mute_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_set_mute" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_set_mute" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.SetMuteRequest.pb( + securitycenter_service.SetMuteRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = finding.Finding.to_json(finding.Finding()) + + request = securitycenter_service.SetMuteRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = finding.Finding() + + client.set_mute( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_set_mute_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.SetMuteRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/sources/sample2/findings/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.set_mute(request) + + +def test_set_mute_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = finding.Finding() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "organizations/sample1/sources/sample2/findings/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + mute=finding.Finding.Mute.MUTED, + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.set_mute(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=organizations/*/sources/*/findings/*}:setMute" + % client.transport._host, + args[1], + ) + + +def test_set_mute_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.set_mute( + securitycenter_service.SetMuteRequest(), + name="name_value", + mute=finding.Finding.Mute.MUTED, + ) + + +def test_set_mute_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + iam_policy_pb2.TestIamPermissionsRequest, + dict, + ], +) +def test_test_iam_permissions_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = iam_policy_pb2.TestIamPermissionsResponse( + permissions=["permissions_value"], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.test_iam_permissions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, iam_policy_pb2.TestIamPermissionsResponse) + assert response.permissions == ["permissions_value"] + + +def test_test_iam_permissions_rest_required_fields( + request_type=iam_policy_pb2.TestIamPermissionsRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request_init["resource"] = "" + request_init["permissions"] = "" + request = request_type(**request_init) + pb_request = request + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).test_iam_permissions._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["resource"] = "resource_value" + jsonified_request["permissions"] = "permissions_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).test_iam_permissions._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "resource" in jsonified_request + assert jsonified_request["resource"] == "resource_value" + assert "permissions" in jsonified_request + assert jsonified_request["permissions"] == "permissions_value" + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = iam_policy_pb2.TestIamPermissionsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.test_iam_permissions(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_test_iam_permissions_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.test_iam_permissions._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "resource", + "permissions", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_test_iam_permissions_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_test_iam_permissions" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_test_iam_permissions" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = iam_policy_pb2.TestIamPermissionsRequest() + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + iam_policy_pb2.TestIamPermissionsResponse() + ) + + request = iam_policy_pb2.TestIamPermissionsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = iam_policy_pb2.TestIamPermissionsResponse() + + client.test_iam_permissions( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_test_iam_permissions_rest_bad_request( + transport: str = "rest", request_type=iam_policy_pb2.TestIamPermissionsRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "organizations/sample1/sources/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.test_iam_permissions(request) + + +def test_test_iam_permissions_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = iam_policy_pb2.TestIamPermissionsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"resource": "organizations/sample1/sources/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + resource="resource_value", + permissions=["permissions_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.test_iam_permissions(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{resource=organizations/*/sources/*}:testIamPermissions" + % client.transport._host, + args[1], + ) + + +def test_test_iam_permissions_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.test_iam_permissions( + iam_policy_pb2.TestIamPermissionsRequest(), + resource="resource_value", + permissions=["permissions_value"], + ) + + +def test_test_iam_permissions_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateBigQueryExportRequest, + dict, + ], +) +def test_update_big_query_export_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "big_query_export": { + "name": "organizations/sample1/locations/sample2/bigQueryExports/sample3" + } + } + request_init["big_query_export"] = { + "name": "organizations/sample1/locations/sample2/bigQueryExports/sample3", + "description": "description_value", + "filter": "filter_value", + "dataset": "dataset_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "most_recent_editor": "most_recent_editor_value", + "principal": "principal_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.UpdateBigQueryExportRequest.meta.fields[ + "big_query_export" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["big_query_export"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["big_query_export"][field])): + del request_init["big_query_export"][field][i][subfield] + else: + del request_init["big_query_export"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = bigquery_export.BigQueryExport( + name="name_value", + description="description_value", + filter="filter_value", + dataset="dataset_value", + most_recent_editor="most_recent_editor_value", + principal="principal_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = bigquery_export.BigQueryExport.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_big_query_export(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, bigquery_export.BigQueryExport) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.dataset == "dataset_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.principal == "principal_value" + + +def test_update_big_query_export_rest_required_fields( + request_type=securitycenter_service.UpdateBigQueryExportRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_big_query_export._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_big_query_export._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = bigquery_export.BigQueryExport() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = bigquery_export.BigQueryExport.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_big_query_export(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_big_query_export_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_big_query_export._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("bigQueryExport",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_big_query_export_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_update_big_query_export" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_update_big_query_export" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.UpdateBigQueryExportRequest.pb( + securitycenter_service.UpdateBigQueryExportRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = bigquery_export.BigQueryExport.to_json( + bigquery_export.BigQueryExport() + ) + + request = securitycenter_service.UpdateBigQueryExportRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = bigquery_export.BigQueryExport() + + client.update_big_query_export( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_big_query_export_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.UpdateBigQueryExportRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "big_query_export": { + "name": "organizations/sample1/locations/sample2/bigQueryExports/sample3" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_big_query_export(request) + + +def test_update_big_query_export_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = bigquery_export.BigQueryExport() + + # get arguments that satisfy an http rule for this method + sample_request = { + "big_query_export": { + "name": "organizations/sample1/locations/sample2/bigQueryExports/sample3" + } + } + + # get truthy value for each flattened field + mock_args = dict( + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = bigquery_export.BigQueryExport.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_big_query_export(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{big_query_export.name=organizations/*/locations/*/bigQueryExports/*}" + % client.transport._host, + args[1], + ) + + +def test_update_big_query_export_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_big_query_export( + securitycenter_service.UpdateBigQueryExportRequest(), + big_query_export=bigquery_export.BigQueryExport(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_big_query_export_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateExternalSystemRequest, + dict, + ], +) +def test_update_external_system_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "external_system": { + "name": "organizations/sample1/sources/sample2/findings/sample3/externalSystems/sample4" + } + } + request_init["external_system"] = { + "name": "organizations/sample1/sources/sample2/findings/sample3/externalSystems/sample4", + "assignees": ["assignees_value1", "assignees_value2"], + "external_uid": "external_uid_value", + "status": "status_value", + "external_system_update_time": {"seconds": 751, "nanos": 543}, + "case_uri": "case_uri_value", + "case_priority": "case_priority_value", + "case_sla": {}, + "case_create_time": {}, + "case_close_time": {}, + "ticket_info": { + "id": "id_value", + "assignee": "assignee_value", + "description": "description_value", + "uri": "uri_value", + "status": "status_value", + "update_time": {}, + }, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.UpdateExternalSystemRequest.meta.fields[ + "external_system" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["external_system"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["external_system"][field])): + del request_init["external_system"][field][i][subfield] + else: + del request_init["external_system"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_external_system.ExternalSystem( + name="name_value", + assignees=["assignees_value"], + external_uid="external_uid_value", + status="status_value", + case_uri="case_uri_value", + case_priority="case_priority_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_external_system.ExternalSystem.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_external_system(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_external_system.ExternalSystem) + assert response.name == "name_value" + assert response.assignees == ["assignees_value"] + assert response.external_uid == "external_uid_value" + assert response.status == "status_value" + assert response.case_uri == "case_uri_value" + assert response.case_priority == "case_priority_value" + + +def test_update_external_system_rest_required_fields( + request_type=securitycenter_service.UpdateExternalSystemRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_external_system._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_external_system._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_external_system.ExternalSystem() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_external_system.ExternalSystem.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_external_system(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_external_system_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_external_system._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("externalSystem",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_external_system_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_update_external_system" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_update_external_system" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.UpdateExternalSystemRequest.pb( + securitycenter_service.UpdateExternalSystemRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcs_external_system.ExternalSystem.to_json( + gcs_external_system.ExternalSystem() + ) + + request = securitycenter_service.UpdateExternalSystemRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_external_system.ExternalSystem() + + client.update_external_system( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_external_system_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.UpdateExternalSystemRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "external_system": { + "name": "organizations/sample1/sources/sample2/findings/sample3/externalSystems/sample4" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_external_system(request) + + +def test_update_external_system_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_external_system.ExternalSystem() + + # get arguments that satisfy an http rule for this method + sample_request = { + "external_system": { + "name": "organizations/sample1/sources/sample2/findings/sample3/externalSystems/sample4" + } + } + + # get truthy value for each flattened field + mock_args = dict( + external_system=gcs_external_system.ExternalSystem(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_external_system.ExternalSystem.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_external_system(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{external_system.name=organizations/*/sources/*/findings/*/externalSystems/*}" + % client.transport._host, + args[1], + ) + + +def test_update_external_system_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_external_system( + securitycenter_service.UpdateExternalSystemRequest(), + external_system=gcs_external_system.ExternalSystem(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_external_system_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateFindingRequest, + dict, + ], +) +def test_update_finding_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "finding": {"name": "organizations/sample1/sources/sample2/findings/sample3"} + } + request_init["finding"] = { + "name": "organizations/sample1/sources/sample2/findings/sample3", + "canonical_name": "canonical_name_value", + "parent": "parent_value", + "resource_name": "resource_name_value", + "state": 1, + "category": "category_value", + "external_uri": "external_uri_value", + "source_properties": {}, + "security_marks": { + "name": "name_value", + "marks": {}, + "canonical_name": "canonical_name_value", + }, + "event_time": {"seconds": 751, "nanos": 543}, + "create_time": {}, + "severity": 1, + "mute": 1, + "finding_class": 1, + "indicator": { + "ip_addresses": ["ip_addresses_value1", "ip_addresses_value2"], + "domains": ["domains_value1", "domains_value2"], + "signatures": [ + { + "memory_hash_signature": { + "binary_family": "binary_family_value", + "detections": [ + {"binary": "binary_value", "percent_pages_matched": 0.2197} + ], + }, + "yara_rule_signature": {"yara_rule": "yara_rule_value"}, + "signature_type": 1, + } + ], + "uris": ["uris_value1", "uris_value2"], + }, + "vulnerability": { + "cve": { + "id": "id_value", + "references": [{"source": "source_value", "uri": "uri_value"}], + "cvssv3": { + "base_score": 0.1046, + "attack_vector": 1, + "attack_complexity": 1, + "privileges_required": 1, + "user_interaction": 1, + "scope": 1, + "confidentiality_impact": 1, + "integrity_impact": 1, + "availability_impact": 1, + }, + "upstream_fix_available": True, + "impact": 1, + "exploitation_activity": 1, + "observed_in_the_wild": True, + "zero_day": True, + }, + "offending_package": { + "package_name": "package_name_value", + "cpe_uri": "cpe_uri_value", + "package_type": "package_type_value", + "package_version": "package_version_value", + }, + "fixed_package": {}, + "security_bulletin": { + "bulletin_id": "bulletin_id_value", + "submission_time": {}, + "suggested_upgrade_version": "suggested_upgrade_version_value", + }, + }, + "mute_update_time": {}, + "external_systems": {}, + "mitre_attack": { + "primary_tactic": 1, + "primary_techniques": [49], + "additional_tactics": [1], + "additional_techniques": [49], + "version": "version_value", + }, + "access": { + "principal_email": "principal_email_value", + "caller_ip": "caller_ip_value", + "caller_ip_geo": {"region_code": "region_code_value"}, + "user_agent_family": "user_agent_family_value", + "user_agent": "user_agent_value", + "service_name": "service_name_value", + "method_name": "method_name_value", + "principal_subject": "principal_subject_value", + "service_account_key_name": "service_account_key_name_value", + "service_account_delegation_info": [ + { + "principal_email": "principal_email_value", + "principal_subject": "principal_subject_value", + } + ], + "user_name": "user_name_value", + }, + "connections": [ + { + "destination_ip": "destination_ip_value", + "destination_port": 1734, + "source_ip": "source_ip_value", + "source_port": 1205, + "protocol": 1, + } + ], + "mute_initiator": "mute_initiator_value", + "processes": [ + { + "name": "name_value", + "binary": { + "path": "path_value", + "size": 443, + "sha256": "sha256_value", + "hashed_size": 1159, + "partially_hashed": True, + "contents": "contents_value", + "disk_path": { + "partition_uuid": "partition_uuid_value", + "relative_path": "relative_path_value", + }, + }, + "libraries": {}, + "script": {}, + "args": ["args_value1", "args_value2"], + "arguments_truncated": True, + "env_variables": [{"name": "name_value", "val": "val_value"}], + "env_variables_truncated": True, + "pid": 317, + "parent_pid": 1062, + } + ], + "contacts": {}, + "compliances": [ + { + "standard": "standard_value", + "version": "version_value", + "ids": ["ids_value1", "ids_value2"], + } + ], + "parent_display_name": "parent_display_name_value", + "description": "description_value", + "exfiltration": { + "sources": [ + { + "name": "name_value", + "components": ["components_value1", "components_value2"], + } + ], + "targets": {}, + "total_exfiltrated_bytes": 2469, + }, + "iam_bindings": [{"action": 1, "role": "role_value", "member": "member_value"}], + "next_steps": "next_steps_value", + "module_name": "module_name_value", + "containers": [ + { + "name": "name_value", + "uri": "uri_value", + "image_id": "image_id_value", + "labels": [{"name": "name_value", "value": "value_value"}], + "create_time": {}, + } + ], + "kubernetes": { + "pods": [ + {"ns": "ns_value", "name": "name_value", "labels": {}, "containers": {}} + ], + "nodes": [{"name": "name_value"}], + "node_pools": [{"name": "name_value", "nodes": {}}], + "roles": [{"kind": 1, "ns": "ns_value", "name": "name_value"}], + "bindings": [ + { + "ns": "ns_value", + "name": "name_value", + "role": {}, + "subjects": [{"kind": 1, "ns": "ns_value", "name": "name_value"}], + } + ], + "access_reviews": [ + { + "group": "group_value", + "ns": "ns_value", + "name": "name_value", + "resource": "resource_value", + "subresource": "subresource_value", + "verb": "verb_value", + "version": "version_value", + } + ], + "objects": [ + { + "group": "group_value", + "kind": "kind_value", + "ns": "ns_value", + "name": "name_value", + "containers": {}, + } + ], + }, + "database": { + "name": "name_value", + "display_name": "display_name_value", + "user_name": "user_name_value", + "query": "query_value", + "grantees": ["grantees_value1", "grantees_value2"], + "version": "version_value", + }, + "attack_exposure": { + "score": 0.54, + "latest_calculation_time": {}, + "attack_exposure_result": "attack_exposure_result_value", + "state": 1, + "exposed_high_value_resources_count": 3637, + "exposed_medium_value_resources_count": 3862, + "exposed_low_value_resources_count": 3559, + }, + "files": {}, + "cloud_dlp_inspection": { + "inspect_job": "inspect_job_value", + "info_type": "info_type_value", + "info_type_count": 1621, + "full_scan": True, + }, + "cloud_dlp_data_profile": { + "data_profile": "data_profile_value", + "parent_type": 1, + }, + "kernel_rootkit": { + "name": "name_value", + "unexpected_code_modification": True, + "unexpected_read_only_data_modification": True, + "unexpected_ftrace_handler": True, + "unexpected_kprobe_handler": True, + "unexpected_kernel_code_pages": True, + "unexpected_system_call_handler": True, + "unexpected_interrupt_handler": True, + "unexpected_processes_in_runqueue": True, + }, + "org_policies": [{"name": "name_value"}], + "application": {"base_uri": "base_uri_value", "full_uri": "full_uri_value"}, + "backup_disaster_recovery": { + "backup_template": "backup_template_value", + "policies": ["policies_value1", "policies_value2"], + "host": "host_value", + "applications": ["applications_value1", "applications_value2"], + "storage_pool": "storage_pool_value", + "policy_options": ["policy_options_value1", "policy_options_value2"], + "profile": "profile_value", + "appliance": "appliance_value", + "backup_type": "backup_type_value", + "backup_create_time": {}, + }, + "security_posture": { + "name": "name_value", + "revision_id": "revision_id_value", + "posture_deployment_resource": "posture_deployment_resource_value", + "posture_deployment": "posture_deployment_value", + "changed_policy": "changed_policy_value", + "policy_set": "policy_set_value", + "policy": "policy_value", + "policy_drift_details": [ + { + "field": "field_value", + "expected_value": "expected_value_value", + "detected_value": "detected_value_value", + } + ], + }, + "log_entries": [ + { + "cloud_logging_entry": { + "insert_id": "insert_id_value", + "log_id": "log_id_value", + "resource_container": "resource_container_value", + "timestamp": {}, + } + } + ], + "load_balancers": [{"name": "name_value"}], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.UpdateFindingRequest.meta.fields["finding"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["finding"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["finding"][field])): + del request_init["finding"][field][i][subfield] + else: + del request_init["finding"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_finding.Finding( + name="name_value", + canonical_name="canonical_name_value", + parent="parent_value", + resource_name="resource_name_value", + state=gcs_finding.Finding.State.ACTIVE, + category="category_value", + external_uri="external_uri_value", + severity=gcs_finding.Finding.Severity.CRITICAL, + mute=gcs_finding.Finding.Mute.MUTED, + finding_class=gcs_finding.Finding.FindingClass.THREAT, + mute_initiator="mute_initiator_value", + parent_display_name="parent_display_name_value", + description="description_value", + next_steps="next_steps_value", + module_name="module_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_finding(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_finding.Finding) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + assert response.parent == "parent_value" + assert response.resource_name == "resource_name_value" + assert response.state == gcs_finding.Finding.State.ACTIVE + assert response.category == "category_value" + assert response.external_uri == "external_uri_value" + assert response.severity == gcs_finding.Finding.Severity.CRITICAL + assert response.mute == gcs_finding.Finding.Mute.MUTED + assert response.finding_class == gcs_finding.Finding.FindingClass.THREAT + assert response.mute_initiator == "mute_initiator_value" + assert response.parent_display_name == "parent_display_name_value" + assert response.description == "description_value" + assert response.next_steps == "next_steps_value" + assert response.module_name == "module_name_value" + + +def test_update_finding_rest_required_fields( + request_type=securitycenter_service.UpdateFindingRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_finding._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_finding._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_finding.Finding() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_finding(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_finding_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_finding._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("finding",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_finding_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_update_finding" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_update_finding" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.UpdateFindingRequest.pb( + securitycenter_service.UpdateFindingRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcs_finding.Finding.to_json(gcs_finding.Finding()) + + request = securitycenter_service.UpdateFindingRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_finding.Finding() + + client.update_finding( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_finding_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.UpdateFindingRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "finding": {"name": "organizations/sample1/sources/sample2/findings/sample3"} + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_finding(request) + + +def test_update_finding_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_finding.Finding() + + # get arguments that satisfy an http rule for this method + sample_request = { + "finding": { + "name": "organizations/sample1/sources/sample2/findings/sample3" + } + } + + # get truthy value for each flattened field + mock_args = dict( + finding=gcs_finding.Finding(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_finding.Finding.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_finding(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{finding.name=organizations/*/sources/*/findings/*}" + % client.transport._host, + args[1], + ) + + +def test_update_finding_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_finding( + securitycenter_service.UpdateFindingRequest(), + finding=gcs_finding.Finding(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_finding_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateMuteConfigRequest, + dict, + ], +) +def test_update_mute_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "mute_config": {"name": "organizations/sample1/muteConfigs/sample2"} + } + request_init["mute_config"] = { + "name": "organizations/sample1/muteConfigs/sample2", + "description": "description_value", + "filter": "filter_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "most_recent_editor": "most_recent_editor_value", + "type_": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.UpdateMuteConfigRequest.meta.fields[ + "mute_config" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["mute_config"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["mute_config"][field])): + del request_init["mute_config"][field][i][subfield] + else: + del request_init["mute_config"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_mute_config.MuteConfig( + name="name_value", + description="description_value", + filter="filter_value", + most_recent_editor="most_recent_editor_value", + type_=gcs_mute_config.MuteConfig.MuteConfigType.STATIC, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_mute_config.MuteConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_mute_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_mute_config.MuteConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.filter == "filter_value" + assert response.most_recent_editor == "most_recent_editor_value" + assert response.type_ == gcs_mute_config.MuteConfig.MuteConfigType.STATIC + + +def test_update_mute_config_rest_required_fields( + request_type=securitycenter_service.UpdateMuteConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_mute_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_mute_config._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_mute_config.MuteConfig() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_mute_config.MuteConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_mute_config(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_mute_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_mute_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("muteConfig",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_mute_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_update_mute_config" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_update_mute_config" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.UpdateMuteConfigRequest.pb( + securitycenter_service.UpdateMuteConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcs_mute_config.MuteConfig.to_json( + gcs_mute_config.MuteConfig() + ) + + request = securitycenter_service.UpdateMuteConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_mute_config.MuteConfig() + + client.update_mute_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_mute_config_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.UpdateMuteConfigRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "mute_config": {"name": "organizations/sample1/muteConfigs/sample2"} + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_mute_config(request) + + +def test_update_mute_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_mute_config.MuteConfig() + + # get arguments that satisfy an http rule for this method + sample_request = { + "mute_config": {"name": "organizations/sample1/muteConfigs/sample2"} + } + + # get truthy value for each flattened field + mock_args = dict( + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_mute_config.MuteConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_mute_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{mute_config.name=organizations/*/muteConfigs/*}" + % client.transport._host, + args[1], + ) + + +def test_update_mute_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_mute_config( + securitycenter_service.UpdateMuteConfigRequest(), + mute_config=gcs_mute_config.MuteConfig(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_mute_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateNotificationConfigRequest, + dict, + ], +) +def test_update_notification_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "notification_config": { + "name": "organizations/sample1/locations/sample2/notificationConfigs/sample3" + } + } + request_init["notification_config"] = { + "name": "organizations/sample1/locations/sample2/notificationConfigs/sample3", + "description": "description_value", + "pubsub_topic": "pubsub_topic_value", + "service_account": "service_account_value", + "streaming_config": {"filter": "filter_value"}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.UpdateNotificationConfigRequest.meta.fields[ + "notification_config" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["notification_config"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["notification_config"][field])): + del request_init["notification_config"][field][i][subfield] + else: + del request_init["notification_config"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_notification_config.NotificationConfig( + name="name_value", + description="description_value", + pubsub_topic="pubsub_topic_value", + service_account="service_account_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_notification_config.NotificationConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_notification_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_notification_config.NotificationConfig) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.pubsub_topic == "pubsub_topic_value" + assert response.service_account == "service_account_value" + + +def test_update_notification_config_rest_required_fields( + request_type=securitycenter_service.UpdateNotificationConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_notification_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_notification_config._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_notification_config.NotificationConfig() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_notification_config.NotificationConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_notification_config(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_notification_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_notification_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("notificationConfig",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_notification_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_update_notification_config" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_update_notification_config" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.UpdateNotificationConfigRequest.pb( + securitycenter_service.UpdateNotificationConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcs_notification_config.NotificationConfig.to_json( + gcs_notification_config.NotificationConfig() + ) + + request = securitycenter_service.UpdateNotificationConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_notification_config.NotificationConfig() + + client.update_notification_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_notification_config_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.UpdateNotificationConfigRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "notification_config": { + "name": "organizations/sample1/locations/sample2/notificationConfigs/sample3" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_notification_config(request) + + +def test_update_notification_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_notification_config.NotificationConfig() + + # get arguments that satisfy an http rule for this method + sample_request = { + "notification_config": { + "name": "organizations/sample1/locations/sample2/notificationConfigs/sample3" + } + } + + # get truthy value for each flattened field + mock_args = dict( + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_notification_config.NotificationConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_notification_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{notification_config.name=organizations/*/locations/*/notificationConfigs/*}" + % client.transport._host, + args[1], + ) + + +def test_update_notification_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_notification_config( + securitycenter_service.UpdateNotificationConfigRequest(), + notification_config=gcs_notification_config.NotificationConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_notification_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateResourceValueConfigRequest, + dict, + ], +) +def test_update_resource_value_config_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "resource_value_config": { + "name": "organizations/sample1/resourceValueConfigs/sample2" + } + } + request_init["resource_value_config"] = { + "name": "organizations/sample1/resourceValueConfigs/sample2", + "resource_value": 1, + "tag_values": ["tag_values_value1", "tag_values_value2"], + "resource_type": "resource_type_value", + "scope": "scope_value", + "resource_labels_selector": {}, + "description": "description_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "sensitive_data_protection_mapping": { + "high_sensitivity_mapping": 1, + "medium_sensitivity_mapping": 1, + }, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.UpdateResourceValueConfigRequest.meta.fields[ + "resource_value_config" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init[ + "resource_value_config" + ].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["resource_value_config"][field])): + del request_init["resource_value_config"][field][i][subfield] + else: + del request_init["resource_value_config"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_resource_value_config.ResourceValueConfig( + name="name_value", + resource_value=gcs_resource_value_config.ResourceValue.HIGH, + tag_values=["tag_values_value"], + resource_type="resource_type_value", + scope="scope_value", + description="description_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_resource_value_config.ResourceValueConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_resource_value_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_resource_value_config.ResourceValueConfig) + assert response.name == "name_value" + assert response.resource_value == gcs_resource_value_config.ResourceValue.HIGH + assert response.tag_values == ["tag_values_value"] + assert response.resource_type == "resource_type_value" + assert response.scope == "scope_value" + assert response.description == "description_value" + + +def test_update_resource_value_config_rest_required_fields( + request_type=securitycenter_service.UpdateResourceValueConfigRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_resource_value_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_resource_value_config._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_resource_value_config.ResourceValueConfig() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_resource_value_config.ResourceValueConfig.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_resource_value_config(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_resource_value_config_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_resource_value_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("resourceValueConfig",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_resource_value_config_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_update_resource_value_config" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_update_resource_value_config" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.UpdateResourceValueConfigRequest.pb( + securitycenter_service.UpdateResourceValueConfigRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = ( + gcs_resource_value_config.ResourceValueConfig.to_json( + gcs_resource_value_config.ResourceValueConfig() + ) + ) + + request = securitycenter_service.UpdateResourceValueConfigRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_resource_value_config.ResourceValueConfig() + + client.update_resource_value_config( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_resource_value_config_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.UpdateResourceValueConfigRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "resource_value_config": { + "name": "organizations/sample1/resourceValueConfigs/sample2" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_resource_value_config(request) + + +def test_update_resource_value_config_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_resource_value_config.ResourceValueConfig() + + # get arguments that satisfy an http rule for this method + sample_request = { + "resource_value_config": { + "name": "organizations/sample1/resourceValueConfigs/sample2" + } + } + + # get truthy value for each flattened field + mock_args = dict( + resource_value_config=gcs_resource_value_config.ResourceValueConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_resource_value_config.ResourceValueConfig.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_resource_value_config(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{resource_value_config.name=organizations/*/resourceValueConfigs/*}" + % client.transport._host, + args[1], + ) + + +def test_update_resource_value_config_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_resource_value_config( + securitycenter_service.UpdateResourceValueConfigRequest(), + resource_value_config=gcs_resource_value_config.ResourceValueConfig( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_resource_value_config_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateSecurityMarksRequest, + dict, + ], +) +def test_update_security_marks_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "security_marks": { + "name": "organizations/sample1/sources/sample2/findings/sample3/securityMarks" + } + } + request_init["security_marks"] = { + "name": "organizations/sample1/sources/sample2/findings/sample3/securityMarks", + "marks": {}, + "canonical_name": "canonical_name_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.UpdateSecurityMarksRequest.meta.fields[ + "security_marks" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["security_marks"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["security_marks"][field])): + del request_init["security_marks"][field][i][subfield] + else: + del request_init["security_marks"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_security_marks.SecurityMarks( + name="name_value", + canonical_name="canonical_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_security_marks.SecurityMarks.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_security_marks(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_security_marks.SecurityMarks) + assert response.name == "name_value" + assert response.canonical_name == "canonical_name_value" + + +def test_update_security_marks_rest_required_fields( + request_type=securitycenter_service.UpdateSecurityMarksRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_security_marks._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_security_marks._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_security_marks.SecurityMarks() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_security_marks.SecurityMarks.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_security_marks(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_security_marks_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_security_marks._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("securityMarks",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_security_marks_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_update_security_marks" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_update_security_marks" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.UpdateSecurityMarksRequest.pb( + securitycenter_service.UpdateSecurityMarksRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcs_security_marks.SecurityMarks.to_json( + gcs_security_marks.SecurityMarks() + ) + + request = securitycenter_service.UpdateSecurityMarksRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_security_marks.SecurityMarks() + + client.update_security_marks( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_security_marks_rest_bad_request( + transport: str = "rest", + request_type=securitycenter_service.UpdateSecurityMarksRequest, +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "security_marks": { + "name": "organizations/sample1/sources/sample2/findings/sample3/securityMarks" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_security_marks(request) + + +def test_update_security_marks_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_security_marks.SecurityMarks() + + # get arguments that satisfy an http rule for this method + sample_request = { + "security_marks": { + "name": "organizations/sample1/sources/sample2/findings/sample3/securityMarks" + } + } + + # get truthy value for each flattened field + mock_args = dict( + security_marks=gcs_security_marks.SecurityMarks(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_security_marks.SecurityMarks.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_security_marks(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{security_marks.name=organizations/*/sources/*/findings/*/securityMarks}" + % client.transport._host, + args[1], + ) + + +def test_update_security_marks_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_security_marks( + securitycenter_service.UpdateSecurityMarksRequest(), + security_marks=gcs_security_marks.SecurityMarks(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_security_marks_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + securitycenter_service.UpdateSourceRequest, + dict, + ], +) +def test_update_source_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"source": {"name": "organizations/sample1/sources/sample2"}} + request_init["source"] = { + "name": "organizations/sample1/sources/sample2", + "display_name": "display_name_value", + "description": "description_value", + "canonical_name": "canonical_name_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = securitycenter_service.UpdateSourceRequest.meta.fields["source"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["source"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["source"][field])): + del request_init["source"][field][i][subfield] + else: + del request_init["source"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_source.Source( + name="name_value", + display_name="display_name_value", + description="description_value", + canonical_name="canonical_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_source.Source.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_source(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcs_source.Source) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.canonical_name == "canonical_name_value" + + +def test_update_source_rest_required_fields( + request_type=securitycenter_service.UpdateSourceRequest, +): + transport_class = transports.SecurityCenterRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_source._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_source._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcs_source.Source() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcs_source.Source.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_source(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_source_rest_unset_required_fields(): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_source._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("source",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_source_rest_interceptors(null_interceptor): + transport = transports.SecurityCenterRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SecurityCenterRestInterceptor(), + ) + client = SecurityCenterClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SecurityCenterRestInterceptor, "post_update_source" + ) as post, mock.patch.object( + transports.SecurityCenterRestInterceptor, "pre_update_source" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = securitycenter_service.UpdateSourceRequest.pb( + securitycenter_service.UpdateSourceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = gcs_source.Source.to_json(gcs_source.Source()) + + request = securitycenter_service.UpdateSourceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcs_source.Source() + + client.update_source( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_source_rest_bad_request( + transport: str = "rest", request_type=securitycenter_service.UpdateSourceRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"source": {"name": "organizations/sample1/sources/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_source(request) + + +def test_update_source_rest_flattened(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcs_source.Source() + + # get arguments that satisfy an http rule for this method + sample_request = {"source": {"name": "organizations/sample1/sources/sample2"}} + + # get truthy value for each flattened field + mock_args = dict( + source=gcs_source.Source(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcs_source.Source.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_source(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{source.name=organizations/*/sources/*}" % client.transport._host, + args[1], + ) + + +def test_update_source_rest_flattened_error(transport: str = "rest"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_source( + securitycenter_service.UpdateSourceRequest(), + source=gcs_source.Source(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_update_source_rest_error(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.SecurityCenterGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.SecurityCenterGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SecurityCenterClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.SecurityCenterGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SecurityCenterClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SecurityCenterClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.SecurityCenterGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SecurityCenterClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.SecurityCenterGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = SecurityCenterClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.SecurityCenterGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.SecurityCenterGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SecurityCenterGrpcTransport, + transports.SecurityCenterGrpcAsyncIOTransport, + transports.SecurityCenterRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "rest", + ], +) +def test_transport_kind(transport_name): + transport = SecurityCenterClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.SecurityCenterGrpcTransport, + ) + + +def test_security_center_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.SecurityCenterTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_security_center_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.securitycenter_v2.services.security_center.transports.SecurityCenterTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.SecurityCenterTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "batch_create_resource_value_configs", + "bulk_mute_findings", + "create_big_query_export", + "create_finding", + "create_mute_config", + "create_notification_config", + "create_source", + "delete_big_query_export", + "delete_mute_config", + "delete_notification_config", + "delete_resource_value_config", + "get_big_query_export", + "get_simulation", + "get_valued_resource", + "get_iam_policy", + "get_mute_config", + "get_notification_config", + "get_resource_value_config", + "get_source", + "group_findings", + "list_attack_paths", + "list_big_query_exports", + "list_findings", + "list_mute_configs", + "list_notification_configs", + "list_resource_value_configs", + "list_sources", + "list_valued_resources", + "set_finding_state", + "set_iam_policy", + "set_mute", + "test_iam_permissions", + "update_big_query_export", + "update_external_system", + "update_finding", + "update_mute_config", + "update_notification_config", + "update_resource_value_config", + "update_security_marks", + "update_source", + "get_operation", + "cancel_operation", + "delete_operation", + "list_operations", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_security_center_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.securitycenter_v2.services.security_center.transports.SecurityCenterTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SecurityCenterTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_security_center_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.cloud.securitycenter_v2.services.security_center.transports.SecurityCenterTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SecurityCenterTransport() + adc.assert_called_once() + + +def test_security_center_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + SecurityCenterClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SecurityCenterGrpcTransport, + transports.SecurityCenterGrpcAsyncIOTransport, + ], +) +def test_security_center_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SecurityCenterGrpcTransport, + transports.SecurityCenterGrpcAsyncIOTransport, + transports.SecurityCenterRestTransport, + ], +) +def test_security_center_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.SecurityCenterGrpcTransport, grpc_helpers), + (transports.SecurityCenterGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_security_center_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "securitycenter.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="securitycenter.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SecurityCenterGrpcTransport, + transports.SecurityCenterGrpcAsyncIOTransport, + ], +) +def test_security_center_grpc_transport_client_cert_source_for_mtls(transport_class): + cred = ga_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=None, + 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_security_center_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.SecurityCenterRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_security_center_rest_lro_client(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_security_center_host_no_port(transport_name): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="securitycenter.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "securitycenter.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://securitycenter.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_security_center_host_with_port(transport_name): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="securitycenter.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "securitycenter.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://securitycenter.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_security_center_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = SecurityCenterClient( + credentials=creds1, + transport=transport_name, + ) + client2 = SecurityCenterClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.batch_create_resource_value_configs._session + session2 = client2.transport.batch_create_resource_value_configs._session + assert session1 != session2 + session1 = client1.transport.bulk_mute_findings._session + session2 = client2.transport.bulk_mute_findings._session + assert session1 != session2 + session1 = client1.transport.create_big_query_export._session + session2 = client2.transport.create_big_query_export._session + assert session1 != session2 + session1 = client1.transport.create_finding._session + session2 = client2.transport.create_finding._session + assert session1 != session2 + session1 = client1.transport.create_mute_config._session + session2 = client2.transport.create_mute_config._session + assert session1 != session2 + session1 = client1.transport.create_notification_config._session + session2 = client2.transport.create_notification_config._session + assert session1 != session2 + session1 = client1.transport.create_source._session + session2 = client2.transport.create_source._session + assert session1 != session2 + session1 = client1.transport.delete_big_query_export._session + session2 = client2.transport.delete_big_query_export._session + assert session1 != session2 + session1 = client1.transport.delete_mute_config._session + session2 = client2.transport.delete_mute_config._session + assert session1 != session2 + session1 = client1.transport.delete_notification_config._session + session2 = client2.transport.delete_notification_config._session + assert session1 != session2 + session1 = client1.transport.delete_resource_value_config._session + session2 = client2.transport.delete_resource_value_config._session + assert session1 != session2 + session1 = client1.transport.get_big_query_export._session + session2 = client2.transport.get_big_query_export._session + assert session1 != session2 + session1 = client1.transport.get_simulation._session + session2 = client2.transport.get_simulation._session + assert session1 != session2 + session1 = client1.transport.get_valued_resource._session + session2 = client2.transport.get_valued_resource._session + assert session1 != session2 + session1 = client1.transport.get_iam_policy._session + session2 = client2.transport.get_iam_policy._session + assert session1 != session2 + session1 = client1.transport.get_mute_config._session + session2 = client2.transport.get_mute_config._session + assert session1 != session2 + session1 = client1.transport.get_notification_config._session + session2 = client2.transport.get_notification_config._session + assert session1 != session2 + session1 = client1.transport.get_resource_value_config._session + session2 = client2.transport.get_resource_value_config._session + assert session1 != session2 + session1 = client1.transport.get_source._session + session2 = client2.transport.get_source._session + assert session1 != session2 + session1 = client1.transport.group_findings._session + session2 = client2.transport.group_findings._session + assert session1 != session2 + session1 = client1.transport.list_attack_paths._session + session2 = client2.transport.list_attack_paths._session + assert session1 != session2 + session1 = client1.transport.list_big_query_exports._session + session2 = client2.transport.list_big_query_exports._session + assert session1 != session2 + session1 = client1.transport.list_findings._session + session2 = client2.transport.list_findings._session + assert session1 != session2 + session1 = client1.transport.list_mute_configs._session + session2 = client2.transport.list_mute_configs._session + assert session1 != session2 + session1 = client1.transport.list_notification_configs._session + session2 = client2.transport.list_notification_configs._session + assert session1 != session2 + session1 = client1.transport.list_resource_value_configs._session + session2 = client2.transport.list_resource_value_configs._session + assert session1 != session2 + session1 = client1.transport.list_sources._session + session2 = client2.transport.list_sources._session + assert session1 != session2 + session1 = client1.transport.list_valued_resources._session + session2 = client2.transport.list_valued_resources._session + assert session1 != session2 + session1 = client1.transport.set_finding_state._session + session2 = client2.transport.set_finding_state._session + assert session1 != session2 + session1 = client1.transport.set_iam_policy._session + session2 = client2.transport.set_iam_policy._session + assert session1 != session2 + session1 = client1.transport.set_mute._session + session2 = client2.transport.set_mute._session + assert session1 != session2 + session1 = client1.transport.test_iam_permissions._session + session2 = client2.transport.test_iam_permissions._session + assert session1 != session2 + session1 = client1.transport.update_big_query_export._session + session2 = client2.transport.update_big_query_export._session + assert session1 != session2 + session1 = client1.transport.update_external_system._session + session2 = client2.transport.update_external_system._session + assert session1 != session2 + session1 = client1.transport.update_finding._session + session2 = client2.transport.update_finding._session + assert session1 != session2 + session1 = client1.transport.update_mute_config._session + session2 = client2.transport.update_mute_config._session + assert session1 != session2 + session1 = client1.transport.update_notification_config._session + session2 = client2.transport.update_notification_config._session + assert session1 != session2 + session1 = client1.transport.update_resource_value_config._session + session2 = client2.transport.update_resource_value_config._session + assert session1 != session2 + session1 = client1.transport.update_security_marks._session + session2 = client2.transport.update_security_marks._session + assert session1 != session2 + session1 = client1.transport.update_source._session + session2 = client2.transport.update_source._session + assert session1 != session2 + + +def test_security_center_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SecurityCenterGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_security_center_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SecurityCenterGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + 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", + [ + transports.SecurityCenterGrpcTransport, + transports.SecurityCenterGrpcAsyncIOTransport, + ], +) +def test_security_center_transport_channel_mtls_with_client_cert_source( + transport_class, +): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + 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", + [ + transports.SecurityCenterGrpcTransport, + transports.SecurityCenterGrpcAsyncIOTransport, + ], +) +def test_security_center_transport_channel_mtls_with_adc(transport_class): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_security_center_grpc_lro_client(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_security_center_grpc_lro_async_client(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_attack_path_path(): + organization = "squid" + simulation = "clam" + valued_resource = "whelk" + attack_path = "octopus" + expected = "organizations/{organization}/simulations/{simulation}/valuedResources/{valued_resource}/attackPaths/{attack_path}".format( + organization=organization, + simulation=simulation, + valued_resource=valued_resource, + attack_path=attack_path, + ) + actual = SecurityCenterClient.attack_path_path( + organization, simulation, valued_resource, attack_path + ) + assert expected == actual + + +def test_parse_attack_path_path(): + expected = { + "organization": "oyster", + "simulation": "nudibranch", + "valued_resource": "cuttlefish", + "attack_path": "mussel", + } + path = SecurityCenterClient.attack_path_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_attack_path_path(path) + assert expected == actual + + +def test_big_query_export_path(): + organization = "winkle" + location = "nautilus" + export = "scallop" + expected = "organizations/{organization}/locations/{location}/bigQueryExports/{export}".format( + organization=organization, + location=location, + export=export, + ) + actual = SecurityCenterClient.big_query_export_path(organization, location, export) + assert expected == actual + + +def test_parse_big_query_export_path(): + expected = { + "organization": "abalone", + "location": "squid", + "export": "clam", + } + path = SecurityCenterClient.big_query_export_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_big_query_export_path(path) + assert expected == actual + + +def test_dlp_job_path(): + project = "whelk" + dlp_job = "octopus" + expected = "projects/{project}/dlpJobs/{dlp_job}".format( + project=project, + dlp_job=dlp_job, + ) + actual = SecurityCenterClient.dlp_job_path(project, dlp_job) + assert expected == actual + + +def test_parse_dlp_job_path(): + expected = { + "project": "oyster", + "dlp_job": "nudibranch", + } + path = SecurityCenterClient.dlp_job_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_dlp_job_path(path) + assert expected == actual + + +def test_external_system_path(): + organization = "cuttlefish" + source = "mussel" + finding = "winkle" + externalsystem = "nautilus" + expected = "organizations/{organization}/sources/{source}/findings/{finding}/externalSystems/{externalsystem}".format( + organization=organization, + source=source, + finding=finding, + externalsystem=externalsystem, + ) + actual = SecurityCenterClient.external_system_path( + organization, source, finding, externalsystem + ) + assert expected == actual + + +def test_parse_external_system_path(): + expected = { + "organization": "scallop", + "source": "abalone", + "finding": "squid", + "externalsystem": "clam", + } + path = SecurityCenterClient.external_system_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_external_system_path(path) + assert expected == actual + + +def test_finding_path(): + organization = "whelk" + source = "octopus" + finding = "oyster" + expected = ( + "organizations/{organization}/sources/{source}/findings/{finding}".format( + organization=organization, + source=source, + finding=finding, + ) + ) + actual = SecurityCenterClient.finding_path(organization, source, finding) + assert expected == actual + + +def test_parse_finding_path(): + expected = { + "organization": "nudibranch", + "source": "cuttlefish", + "finding": "mussel", + } + path = SecurityCenterClient.finding_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_finding_path(path) + assert expected == actual + + +def test_mute_config_path(): + organization = "winkle" + mute_config = "nautilus" + expected = "organizations/{organization}/muteConfigs/{mute_config}".format( + organization=organization, + mute_config=mute_config, + ) + actual = SecurityCenterClient.mute_config_path(organization, mute_config) + assert expected == actual + + +def test_parse_mute_config_path(): + expected = { + "organization": "scallop", + "mute_config": "abalone", + } + path = SecurityCenterClient.mute_config_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_mute_config_path(path) + assert expected == actual + + +def test_notification_config_path(): + organization = "squid" + location = "clam" + notification_config = "whelk" + expected = "organizations/{organization}/locations/{location}/notificationConfigs/{notification_config}".format( + organization=organization, + location=location, + notification_config=notification_config, + ) + actual = SecurityCenterClient.notification_config_path( + organization, location, notification_config + ) + assert expected == actual + + +def test_parse_notification_config_path(): + expected = { + "organization": "octopus", + "location": "oyster", + "notification_config": "nudibranch", + } + path = SecurityCenterClient.notification_config_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_notification_config_path(path) + assert expected == actual + + +def test_policy_path(): + organization = "cuttlefish" + constraint_name = "mussel" + expected = "organizations/{organization}/policies/{constraint_name}".format( + organization=organization, + constraint_name=constraint_name, + ) + actual = SecurityCenterClient.policy_path(organization, constraint_name) + assert expected == actual + + +def test_parse_policy_path(): + expected = { + "organization": "winkle", + "constraint_name": "nautilus", + } + path = SecurityCenterClient.policy_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_policy_path(path) + assert expected == actual + + +def test_resource_value_config_path(): + organization = "scallop" + resource_value_config = "abalone" + expected = "organizations/{organization}/resourceValueConfigs/{resource_value_config}".format( + organization=organization, + resource_value_config=resource_value_config, + ) + actual = SecurityCenterClient.resource_value_config_path( + organization, resource_value_config + ) + assert expected == actual + + +def test_parse_resource_value_config_path(): + expected = { + "organization": "squid", + "resource_value_config": "clam", + } + path = SecurityCenterClient.resource_value_config_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_resource_value_config_path(path) + assert expected == actual + + +def test_security_marks_path(): + organization = "whelk" + asset = "octopus" + expected = "organizations/{organization}/assets/{asset}/securityMarks".format( + organization=organization, + asset=asset, + ) + actual = SecurityCenterClient.security_marks_path(organization, asset) + assert expected == actual + + +def test_parse_security_marks_path(): + expected = { + "organization": "oyster", + "asset": "nudibranch", + } + path = SecurityCenterClient.security_marks_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_security_marks_path(path) + assert expected == actual + + +def test_simulation_path(): + organization = "cuttlefish" + simulation = "mussel" + expected = "organizations/{organization}/simulations/{simulation}".format( + organization=organization, + simulation=simulation, + ) + actual = SecurityCenterClient.simulation_path(organization, simulation) + assert expected == actual + + +def test_parse_simulation_path(): + expected = { + "organization": "winkle", + "simulation": "nautilus", + } + path = SecurityCenterClient.simulation_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_simulation_path(path) + assert expected == actual + + +def test_source_path(): + organization = "scallop" + source = "abalone" + expected = "organizations/{organization}/sources/{source}".format( + organization=organization, + source=source, + ) + actual = SecurityCenterClient.source_path(organization, source) + assert expected == actual + + +def test_parse_source_path(): + expected = { + "organization": "squid", + "source": "clam", + } + path = SecurityCenterClient.source_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_source_path(path) + assert expected == actual + + +def test_table_data_profile_path(): + project = "whelk" + table_profile = "octopus" + expected = "projects/{project}/tableProfiles/{table_profile}".format( + project=project, + table_profile=table_profile, + ) + actual = SecurityCenterClient.table_data_profile_path(project, table_profile) + assert expected == actual + + +def test_parse_table_data_profile_path(): + expected = { + "project": "oyster", + "table_profile": "nudibranch", + } + path = SecurityCenterClient.table_data_profile_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_table_data_profile_path(path) + assert expected == actual + + +def test_topic_path(): + project = "cuttlefish" + topic = "mussel" + expected = "projects/{project}/topics/{topic}".format( + project=project, + topic=topic, + ) + actual = SecurityCenterClient.topic_path(project, topic) + assert expected == actual + + +def test_parse_topic_path(): + expected = { + "project": "winkle", + "topic": "nautilus", + } + path = SecurityCenterClient.topic_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_topic_path(path) + assert expected == actual + + +def test_valued_resource_path(): + organization = "scallop" + simulation = "abalone" + valued_resource = "squid" + expected = "organizations/{organization}/simulations/{simulation}/valuedResources/{valued_resource}".format( + organization=organization, + simulation=simulation, + valued_resource=valued_resource, + ) + actual = SecurityCenterClient.valued_resource_path( + organization, simulation, valued_resource + ) + assert expected == actual + + +def test_parse_valued_resource_path(): + expected = { + "organization": "clam", + "simulation": "whelk", + "valued_resource": "octopus", + } + path = SecurityCenterClient.valued_resource_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_valued_resource_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "oyster" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = SecurityCenterClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = SecurityCenterClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "cuttlefish" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = SecurityCenterClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = SecurityCenterClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "winkle" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = SecurityCenterClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = SecurityCenterClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "scallop" + expected = "projects/{project}".format( + project=project, + ) + actual = SecurityCenterClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = SecurityCenterClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "squid" + location = "clam" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = SecurityCenterClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = SecurityCenterClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = SecurityCenterClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.SecurityCenterTransport, "_prep_wrapped_messages" + ) as prep: + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.SecurityCenterTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = SecurityCenterClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_cancel_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.CancelOperationRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/operations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.cancel_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.CancelOperationRequest, + dict, + ], +) +def test_cancel_operation_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "organizations/sample1/operations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "{}" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.cancel_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.DeleteOperationRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/operations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.DeleteOperationRequest, + dict, + ], +) +def test_delete_operation_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "organizations/sample1/operations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "{}" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_get_operation_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.GetOperationRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/operations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "organizations/sample1/operations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + transport: str = "rest", request_type=operations_pb2.ListOperationsRequest +): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/operations"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {"name": "organizations/sample1/operations"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_delete_operation(transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_operation_async(transport: str = "grpc_asyncio"): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = None + + client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_operation_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_delete_operation_from_dict(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_delete_operation_from_dict_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_cancel_operation(transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_cancel_operation_async(transport: str = "grpc_asyncio"): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_cancel_operation_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = None + + client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_cancel_operation_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_cancel_operation_from_dict(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_cancel_operation_from_dict_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_operation(transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc_asyncio"): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc_asyncio"): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = SecurityCenterAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = SecurityCenterClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (SecurityCenterClient, transports.SecurityCenterGrpcTransport), + (SecurityCenterAsyncClient, transports.SecurityCenterGrpcAsyncIOTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) From 43e63be479ab80d4d3be2c47c3be530db4d30993 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 10:03:24 -0500 Subject: [PATCH 11/13] fix(deps): [google-cloud-container] Exclude google-auth 2.24.0 and 2.25.0 (#12362) - [ ] Regenerate this pull request now. BEGIN_COMMIT_OVERRIDE fix(deps): Exclude google-auth 2.24.0 and 2.25.0 feat: add secondary boot disks field to NodePool API feat: add API to enable Provisioning Request API on existing nodepools docs: Update comment for field `enable_confidential_storage` in message `google.container.v1beta1.NodeConfig` END_COMMIT_OVERRIDE chore: Update gapic-generator-python to v1.14.4 PiperOrigin-RevId: 611561820 Source-Link: https://github.com/googleapis/googleapis/commit/87ef1fe57feede1f23b523f3c7fc4c3f2b92d6d2 Source-Link: https://github.com/googleapis/googleapis-gen/commit/197316137594aafad94dea31226528fbcc39310c Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLWNvbnRhaW5lci8uT3dsQm90LnlhbWwiLCJoIjoiMTk3MzE2MTM3NTk0YWFmYWQ5NGRlYTMxMjI2NTI4ZmJjYzM5MzEwYyJ9 BEGIN_NESTED_COMMIT feat: [google-cloud-container] add secondary boot disks field to NodePool API PiperOrigin-RevId: 610868066 Source-Link: https://github.com/googleapis/googleapis/commit/13c6878a4c2822c6db7b986e717bf57943bf1681 Source-Link: https://github.com/googleapis/googleapis-gen/commit/bc7f831ac006558427689f161bd00c2ed2b6fad9 Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLWNvbnRhaW5lci8uT3dsQm90LnlhbWwiLCJoIjoiYmM3ZjgzMWFjMDA2NTU4NDI3Njg5ZjE2MWJkMDBjMmVkMmI2ZmFkOSJ9 END_NESTED_COMMIT BEGIN_NESTED_COMMIT feat: [google-cloud-container] add API to enable Provisioning Request API on existing nodepools --- docs: A comment for field `enable_confidential_storage` in message `.google.container.v1beta1.NodeConfig` is changed PiperOrigin-RevId: 609809689 Source-Link: https://github.com/googleapis/googleapis/commit/8df1cd698e2fe0b7d1c298dabafdf13aa01c4d39 Source-Link: https://github.com/googleapis/googleapis-gen/commit/f9f58f7014048bfd2c1adac921ee23f20cfb62ab Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLWNsb3VkLWNvbnRhaW5lci8uT3dsQm90LnlhbWwiLCJoIjoiZjlmNThmNzAxNDA0OGJmZDJjMWFkYWM5MjFlZTIzZjIwY2ZiNjJhYiJ9 END_NESTED_COMMIT --------- Co-authored-by: Owl Bot --- .../google/cloud/container/gapic_version.py | 2 +- .../cloud/container_v1/gapic_version.py | 2 +- .../cloud/container_v1beta1/__init__.py | 2 + .../cloud/container_v1beta1/gapic_version.py | 2 +- .../cloud/container_v1beta1/types/__init__.py | 2 + .../types/cluster_service.py | 59 +++++++++++++++++-- .../snippet_metadata_google.container.v1.json | 2 +- ...pet_metadata_google.container.v1beta1.json | 2 +- .../fixup_container_v1beta1_keywords.py | 2 +- packages/google-cloud-container/setup.py | 4 +- 10 files changed, 68 insertions(+), 11 deletions(-) diff --git a/packages/google-cloud-container/google/cloud/container/gapic_version.py b/packages/google-cloud-container/google/cloud/container/gapic_version.py index cc337c45cd67..360a0d13ebdd 100644 --- a/packages/google-cloud-container/google/cloud/container/gapic_version.py +++ b/packages/google-cloud-container/google/cloud/container/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.41.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-container/google/cloud/container_v1/gapic_version.py b/packages/google-cloud-container/google/cloud/container_v1/gapic_version.py index cc337c45cd67..360a0d13ebdd 100644 --- a/packages/google-cloud-container/google/cloud/container_v1/gapic_version.py +++ b/packages/google-cloud-container/google/cloud/container_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.41.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-container/google/cloud/container_v1beta1/__init__.py b/packages/google-cloud-container/google/cloud/container_v1beta1/__init__.py index 0dca9d155e6a..445df45af37c 100644 --- a/packages/google-cloud-container/google/cloud/container_v1beta1/__init__.py +++ b/packages/google-cloud-container/google/cloud/container_v1beta1/__init__.py @@ -159,6 +159,7 @@ ResourceUsageExportConfig, RollbackNodePoolUpgradeRequest, SandboxConfig, + SecondaryBootDisk, SecurityBulletinEvent, SecurityPostureConfig, ServerConfig, @@ -346,6 +347,7 @@ "ResourceUsageExportConfig", "RollbackNodePoolUpgradeRequest", "SandboxConfig", + "SecondaryBootDisk", "SecurityBulletinEvent", "SecurityPostureConfig", "ServerConfig", diff --git a/packages/google-cloud-container/google/cloud/container_v1beta1/gapic_version.py b/packages/google-cloud-container/google/cloud/container_v1beta1/gapic_version.py index cc337c45cd67..360a0d13ebdd 100644 --- a/packages/google-cloud-container/google/cloud/container_v1beta1/gapic_version.py +++ b/packages/google-cloud-container/google/cloud/container_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.41.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-container/google/cloud/container_v1beta1/types/__init__.py b/packages/google-cloud-container/google/cloud/container_v1beta1/types/__init__.py index 4837bfe12f88..762008fff2cb 100644 --- a/packages/google-cloud-container/google/cloud/container_v1beta1/types/__init__.py +++ b/packages/google-cloud-container/google/cloud/container_v1beta1/types/__init__.py @@ -153,6 +153,7 @@ ResourceUsageExportConfig, RollbackNodePoolUpgradeRequest, SandboxConfig, + SecondaryBootDisk, SecurityBulletinEvent, SecurityPostureConfig, ServerConfig, @@ -334,6 +335,7 @@ "ResourceUsageExportConfig", "RollbackNodePoolUpgradeRequest", "SandboxConfig", + "SecondaryBootDisk", "SecurityBulletinEvent", "SecurityPostureConfig", "ServerConfig", diff --git a/packages/google-cloud-container/google/cloud/container_v1beta1/types/cluster_service.py b/packages/google-cloud-container/google/cloud/container_v1beta1/types/cluster_service.py index b0d85e36a70b..21426afa9f22 100644 --- a/packages/google-cloud-container/google/cloud/container_v1beta1/types/cluster_service.py +++ b/packages/google-cloud-container/google/cloud/container_v1beta1/types/cluster_service.py @@ -210,6 +210,7 @@ "Fleet", "ResourceManagerTags", "EnterpriseConfig", + "SecondaryBootDisk", }, ) @@ -723,10 +724,10 @@ class NodeConfig(proto.Message): A map of resource manager tag keys and values to be attached to the nodes. enable_confidential_storage (bool): - Optional. Enable confidential storage on Hyperdisk. - boot_disk_kms_key is required when - enable_confidential_storage is true. This is only available - for private preview. + Optional. Reserved for future use. + secondary_boot_disks (MutableSequence[google.cloud.container_v1beta1.types.SecondaryBootDisk]): + List of secondary boot disks attached to the + nodes. """ machine_type: str = proto.Field( @@ -906,6 +907,11 @@ class NodeConfig(proto.Message): proto.BOOL, number=46, ) + secondary_boot_disks: MutableSequence["SecondaryBootDisk"] = proto.RepeatedField( + proto.MESSAGE, + number=48, + message="SecondaryBootDisk", + ) class AdvancedMachineFeatures(proto.Message): @@ -5142,6 +5148,9 @@ class UpdateNodePoolRequest(proto.Message): Engine firewalls using Network Firewall Policies. Existing tags will be replaced with new values. + queued_provisioning (google.cloud.container_v1beta1.types.NodePool.QueuedProvisioning): + Specifies the configuration of queued + provisioning. """ project_id: str = proto.Field( @@ -5272,6 +5281,11 @@ class UpdateNodePoolRequest(proto.Message): number=39, message="ResourceManagerTags", ) + queued_provisioning: "NodePool.QueuedProvisioning" = proto.Field( + proto.MESSAGE, + number=42, + message="NodePool.QueuedProvisioning", + ) class SetNodePoolAutoscalingRequest(proto.Message): @@ -10372,4 +10386,41 @@ class ClusterTier(proto.Enum): ) +class SecondaryBootDisk(proto.Message): + r"""SecondaryBootDisk represents a persistent disk attached to a + node with special configurations based on its mode. + + Attributes: + mode (google.cloud.container_v1beta1.types.SecondaryBootDisk.Mode): + Disk mode (container image cache, etc.) + disk_image (str): + Fully-qualified resource ID for an existing + disk image. + """ + + class Mode(proto.Enum): + r"""Mode specifies how the secondary boot disk will be used. + This triggers mode-specified logic in the control plane. + + Values: + MODE_UNSPECIFIED (0): + MODE_UNSPECIFIED is when mode is not set. + CONTAINER_IMAGE_CACHE (1): + CONTAINER_IMAGE_CACHE is for using the secondary boot disk + as a container image cache. + """ + MODE_UNSPECIFIED = 0 + CONTAINER_IMAGE_CACHE = 1 + + mode: Mode = proto.Field( + proto.ENUM, + number=1, + enum=Mode, + ) + disk_image: str = proto.Field( + proto.STRING, + number=2, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1.json b/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1.json index 27eca6e11754..477de1eee441 100644 --- a/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1.json +++ b/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-container", - "version": "2.41.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1beta1.json b/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1beta1.json index 1aaec109d1c2..afdb562b267e 100644 --- a/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1beta1.json +++ b/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-container", - "version": "2.41.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-container/scripts/fixup_container_v1beta1_keywords.py b/packages/google-cloud-container/scripts/fixup_container_v1beta1_keywords.py index 7d38a32fd2b4..f31d4ac3b9a7 100644 --- a/packages/google-cloud-container/scripts/fixup_container_v1beta1_keywords.py +++ b/packages/google-cloud-container/scripts/fixup_container_v1beta1_keywords.py @@ -73,7 +73,7 @@ class containerCallTransformer(cst.CSTTransformer): 'start_ip_rotation': ('project_id', 'zone', 'cluster_id', 'name', 'rotate_credentials', ), 'update_cluster': ('project_id', 'zone', 'cluster_id', 'update', 'name', ), 'update_master': ('project_id', 'zone', 'cluster_id', 'master_version', 'name', ), - 'update_node_pool': ('project_id', 'zone', 'cluster_id', 'node_pool_id', 'node_version', 'image_type', 'locations', 'workload_metadata_config', 'name', 'upgrade_settings', 'tags', 'taints', 'labels', 'linux_node_config', 'kubelet_config', 'node_network_config', 'gcfs_config', 'confidential_nodes', 'gvnic', 'etag', 'fast_socket', 'logging_config', 'resource_labels', 'windows_node_config', 'machine_type', 'disk_type', 'disk_size_gb', 'resource_manager_tags', ), + 'update_node_pool': ('project_id', 'zone', 'cluster_id', 'node_pool_id', 'node_version', 'image_type', 'locations', 'workload_metadata_config', 'name', 'upgrade_settings', 'tags', 'taints', 'labels', 'linux_node_config', 'kubelet_config', 'node_network_config', 'gcfs_config', 'confidential_nodes', 'gvnic', 'etag', 'fast_socket', 'logging_config', 'resource_labels', 'windows_node_config', 'machine_type', 'disk_type', 'disk_size_gb', 'resource_manager_tags', 'queued_provisioning', ), } def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: diff --git a/packages/google-cloud-container/setup.py b/packages/google-cloud-container/setup.py index bdc1d1c88181..a7fa778712dc 100644 --- a/packages/google-cloud-container/setup.py +++ b/packages/google-cloud-container/setup.py @@ -40,7 +40,9 @@ dependencies = [ "google-api-core[grpc] >= 1.34.1, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", - "google-auth >= 2.14.1, <3.0.0dev", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", "proto-plus >= 1.22.3, <2.0.0dev", "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] From 31f4b1769c149d26d0f04c05cde39f5544ea8114 Mon Sep 17 00:00:00 2001 From: yoshi-code-bot <70984784+yoshi-code-bot@users.noreply.github.com> Date: Mon, 4 Mar 2024 07:09:28 -0800 Subject: [PATCH 12/13] chore: Update release-please config files (#12394) Update release-please config files --- release-please-config.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/release-please-config.json b/release-please-config.json index afa3f6ef0358..81e57291977f 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -2273,6 +2273,7 @@ "google/cloud/securitycenter_v1/gapic_version.py", "google/cloud/securitycenter_v1beta1/gapic_version.py", "google/cloud/securitycenter_v1p1beta1/gapic_version.py", + "google/cloud/securitycenter_v2/gapic_version.py", { "jsonpath": "$.clientLibrary.version", "path": "samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1.json", @@ -2287,6 +2288,11 @@ "jsonpath": "$.clientLibrary.version", "path": "samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1p1beta1.json", "type": "json" + }, + { + "jsonpath": "$.clientLibrary.version", + "path": "samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v2.json", + "type": "json" } ], "release-type": "python" From c88cdce6ed308d427baeedf4ae88c915d2a214f8 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 10:13:19 -0500 Subject: [PATCH 13/13] chore: release main (#12371) :robot: I have created a release *beep* *boop* ---
google-apps-card: 0.1.0 ## 0.1.0 (2024-03-04) ### Features * add initial files for google.apps.card.v1 ([#12370](https://github.com/googleapis/google-cloud-python/issues/12370)) ([394a05f](https://github.com/googleapis/google-cloud-python/commit/394a05fe2b3d2582c4f161efc574fe8e1625c913))
google-cloud-batch: 0.17.13 ## [0.17.13](https://github.com/googleapis/google-cloud-python/compare/google-cloud-batch-v0.17.12...google-cloud-batch-v0.17.13) (2024-03-04) ### Documentation * [google-cloud-batch] Remove UUID specification in comment ([#12366](https://github.com/googleapis/google-cloud-python/issues/12366)) ([13c7f8f](https://github.com/googleapis/google-cloud-python/commit/13c7f8f24450f520e4021336753c5a9219d52cf6)) * [google-cloud-batch] update description of Job uid field ([13c7f8f](https://github.com/googleapis/google-cloud-python/commit/13c7f8f24450f520e4021336753c5a9219d52cf6))
google-cloud-container: 2.42.0 ## [2.42.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-container-v2.41.0...google-cloud-container-v2.42.0) (2024-03-04) ### Features * add API to enable Provisioning Request API on existing nodepools ([43e63be](https://github.com/googleapis/google-cloud-python/commit/43e63be479ab80d4d3be2c47c3be530db4d30993)) * add secondary boot disks field to NodePool API ([43e63be](https://github.com/googleapis/google-cloud-python/commit/43e63be479ab80d4d3be2c47c3be530db4d30993)) ### Bug Fixes * **deps:** Exclude google-auth 2.24.0 and 2.25.0 ([43e63be](https://github.com/googleapis/google-cloud-python/commit/43e63be479ab80d4d3be2c47c3be530db4d30993)) ### Documentation * Update comment for field `enable_confidential_storage` in message `google.container.v1beta1.NodeConfig` ([43e63be](https://github.com/googleapis/google-cloud-python/commit/43e63be479ab80d4d3be2c47c3be530db4d30993))
google-cloud-parallelstore: 0.1.0 ## 0.1.0 (2024-03-04) ### Features * add initial files for google.cloud.parallelstore.v1beta ([#12368](https://github.com/googleapis/google-cloud-python/issues/12368)) ([db14111](https://github.com/googleapis/google-cloud-python/commit/db1411133fbdd2ee333aca125dd05996c7a95f59))
google-cloud-securitycenter: 1.28.0 ## [1.28.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-securitycenter-v1.27.0...google-cloud-securitycenter-v1.28.0) (2024-03-04) ### Features * Add container.create_time, vulnerability.offending_package, vulnerability.fixed_package, vulnerability.security_bulletin, vulnerability.cve.impact, vulnerability.cve.exploitation_activity, vulnerability.cve.observed_in_the_wild, vulnerability.cve.zero_day to finding's list of attributes ([4450f4c](https://github.com/googleapis/google-cloud-python/commit/4450f4ce787d11cfa11934dbd2acfe194474ca32)) * Add load balancer, log entry, org policy, database.version, exfiltration.total_exfiltrated_bytes, file.disk_path, indicator.signature_type, and kubernetes.objects to finding's list of attributes ([4450f4c](https://github.com/googleapis/google-cloud-python/commit/4450f4ce787d11cfa11934dbd2acfe194474ca32)) * Added security center api V2 client library ([4450f4c](https://github.com/googleapis/google-cloud-python/commit/4450f4ce787d11cfa11934dbd2acfe194474ca32)) ### Bug Fixes * **deps:** Exclude google-auth 2.24.0 and 2.25.0 ([4450f4c](https://github.com/googleapis/google-cloud-python/commit/4450f4ce787d11cfa11934dbd2acfe194474ca32))
--- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- .release-please-manifest.json | 10 +++++----- packages/google-apps-card/CHANGELOG.md | 11 ++++++++++- .../google/apps/card/gapic_version.py | 2 +- .../google/apps/card_v1/gapic_version.py | 2 +- packages/google-cloud-batch/CHANGELOG.md | 8 ++++++++ .../google/cloud/batch/gapic_version.py | 2 +- .../google/cloud/batch_v1/gapic_version.py | 2 +- .../cloud/batch_v1alpha/gapic_version.py | 2 +- ...snippet_metadata_google.cloud.batch.v1.json | 2 +- ...et_metadata_google.cloud.batch.v1alpha.json | 2 +- packages/google-cloud-container/CHANGELOG.md | 18 ++++++++++++++++++ .../google/cloud/container/gapic_version.py | 2 +- .../google/cloud/container_v1/gapic_version.py | 2 +- .../cloud/container_v1beta1/gapic_version.py | 2 +- .../snippet_metadata_google.container.v1.json | 2 +- ...ppet_metadata_google.container.v1beta1.json | 2 +- .../google-cloud-parallelstore/CHANGELOG.md | 11 ++++++++++- .../cloud/parallelstore/gapic_version.py | 2 +- .../parallelstore_v1beta/gapic_version.py | 2 +- .../google-cloud-securitycenter/CHANGELOG.md | 14 ++++++++++++++ .../cloud/securitycenter/gapic_version.py | 2 +- .../cloud/securitycenter_v1/gapic_version.py | 2 +- .../securitycenter_v1beta1/gapic_version.py | 2 +- .../securitycenter_v1p1beta1/gapic_version.py | 2 +- ...etadata_google.cloud.securitycenter.v1.json | 2 +- ...ta_google.cloud.securitycenter.v1beta1.json | 2 +- ..._google.cloud.securitycenter.v1p1beta1.json | 2 +- 27 files changed, 86 insertions(+), 28 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 770b3738bdf4..041ed649756b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -2,7 +2,7 @@ "packages/google-ai-generativelanguage": "0.5.3", "packages/google-analytics-admin": "0.22.6", "packages/google-analytics-data": "0.18.6", - "packages/google-apps-card": "0.0.0", + "packages/google-apps-card": "0.1.0", "packages/google-apps-events-subscriptions": "0.0.0", "packages/google-apps-meet": "0.1.5", "packages/google-apps-script-type": "0.3.7", @@ -22,7 +22,7 @@ "packages/google-cloud-assured-workloads": "1.12.2", "packages/google-cloud-automl": "2.13.2", "packages/google-cloud-bare-metal-solution": "1.7.2", - "packages/google-cloud-batch": "0.17.12", + "packages/google-cloud-batch": "0.17.13", "packages/google-cloud-beyondcorp-appconnections": "0.4.8", "packages/google-cloud-beyondcorp-appconnectors": "0.4.8", "packages/google-cloud-beyondcorp-appgateways": "0.4.8", @@ -50,7 +50,7 @@ "packages/google-cloud-confidentialcomputing": "0.4.6", "packages/google-cloud-config": "0.1.6", "packages/google-cloud-contact-center-insights": "1.17.2", - "packages/google-cloud-container": "2.41.0", + "packages/google-cloud-container": "2.42.0", "packages/google-cloud-containeranalysis": "2.14.2", "packages/google-cloud-contentwarehouse": "0.7.6", "packages/google-cloud-data-fusion": "1.10.2", @@ -110,7 +110,7 @@ "packages/google-cloud-orchestration-airflow": "1.12.0", "packages/google-cloud-os-config": "1.17.2", "packages/google-cloud-os-login": "2.14.2", - "packages/google-cloud-parallelstore": "0.0.0", + "packages/google-cloud-parallelstore": "0.1.0", "packages/google-cloud-phishing-protection": "1.11.2", "packages/google-cloud-policy-troubleshooter": "1.11.2", "packages/google-cloud-policysimulator": "0.1.5", @@ -131,7 +131,7 @@ "packages/google-cloud-scheduler": "2.13.2", "packages/google-cloud-secret-manager": "2.18.2", "packages/google-cloud-securesourcemanager": "0.1.4", - "packages/google-cloud-securitycenter": "1.27.0", + "packages/google-cloud-securitycenter": "1.28.0", "packages/google-cloud-securitycentermanagement": "0.1.6", "packages/google-cloud-service-control": "1.12.0", "packages/google-cloud-service-directory": "1.11.2", diff --git a/packages/google-apps-card/CHANGELOG.md b/packages/google-apps-card/CHANGELOG.md index 5ddad421e08f..0a74f114554f 100644 --- a/packages/google-apps-card/CHANGELOG.md +++ b/packages/google-apps-card/CHANGELOG.md @@ -1 +1,10 @@ -# Changelog \ No newline at end of file +# Changelog + +## 0.1.0 (2024-03-04) + + +### Features + +* add initial files for google.apps.card.v1 ([#12370](https://github.com/googleapis/google-cloud-python/issues/12370)) ([394a05f](https://github.com/googleapis/google-cloud-python/commit/394a05fe2b3d2582c4f161efc574fe8e1625c913)) + +## Changelog diff --git a/packages/google-apps-card/google/apps/card/gapic_version.py b/packages/google-apps-card/google/apps/card/gapic_version.py index 360a0d13ebdd..a7d39deb7a45 100644 --- a/packages/google-apps-card/google/apps/card/gapic_version.py +++ b/packages/google-apps-card/google/apps/card/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} diff --git a/packages/google-apps-card/google/apps/card_v1/gapic_version.py b/packages/google-apps-card/google/apps/card_v1/gapic_version.py index 360a0d13ebdd..a7d39deb7a45 100644 --- a/packages/google-apps-card/google/apps/card_v1/gapic_version.py +++ b/packages/google-apps-card/google/apps/card_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} diff --git a/packages/google-cloud-batch/CHANGELOG.md b/packages/google-cloud-batch/CHANGELOG.md index eb3d565738bd..c9c6ed0733db 100644 --- a/packages/google-cloud-batch/CHANGELOG.md +++ b/packages/google-cloud-batch/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.17.13](https://github.com/googleapis/google-cloud-python/compare/google-cloud-batch-v0.17.12...google-cloud-batch-v0.17.13) (2024-03-04) + + +### Documentation + +* [google-cloud-batch] Remove UUID specification in comment ([#12366](https://github.com/googleapis/google-cloud-python/issues/12366)) ([13c7f8f](https://github.com/googleapis/google-cloud-python/commit/13c7f8f24450f520e4021336753c5a9219d52cf6)) +* [google-cloud-batch] update description of Job uid field ([13c7f8f](https://github.com/googleapis/google-cloud-python/commit/13c7f8f24450f520e4021336753c5a9219d52cf6)) + ## [0.17.12](https://github.com/googleapis/google-cloud-python/compare/google-cloud-batch-v0.17.11...google-cloud-batch-v0.17.12) (2024-02-22) diff --git a/packages/google-cloud-batch/google/cloud/batch/gapic_version.py b/packages/google-cloud-batch/google/cloud/batch/gapic_version.py index 360a0d13ebdd..f082149d8e87 100644 --- a/packages/google-cloud-batch/google/cloud/batch/gapic_version.py +++ b/packages/google-cloud-batch/google/cloud/batch/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.17.13" # {x-release-please-version} diff --git a/packages/google-cloud-batch/google/cloud/batch_v1/gapic_version.py b/packages/google-cloud-batch/google/cloud/batch_v1/gapic_version.py index 360a0d13ebdd..f082149d8e87 100644 --- a/packages/google-cloud-batch/google/cloud/batch_v1/gapic_version.py +++ b/packages/google-cloud-batch/google/cloud/batch_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.17.13" # {x-release-please-version} diff --git a/packages/google-cloud-batch/google/cloud/batch_v1alpha/gapic_version.py b/packages/google-cloud-batch/google/cloud/batch_v1alpha/gapic_version.py index 360a0d13ebdd..f082149d8e87 100644 --- a/packages/google-cloud-batch/google/cloud/batch_v1alpha/gapic_version.py +++ b/packages/google-cloud-batch/google/cloud/batch_v1alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.17.13" # {x-release-please-version} diff --git a/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1.json b/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1.json index e2df1067e4dd..9d035b977cbc 100644 --- a/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1.json +++ b/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-batch", - "version": "0.1.0" + "version": "0.17.13" }, "snippets": [ { diff --git a/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1alpha.json b/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1alpha.json index 4862cc9a6486..e64073c4ef73 100644 --- a/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1alpha.json +++ b/packages/google-cloud-batch/samples/generated_samples/snippet_metadata_google.cloud.batch.v1alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-batch", - "version": "0.1.0" + "version": "0.17.13" }, "snippets": [ { diff --git a/packages/google-cloud-container/CHANGELOG.md b/packages/google-cloud-container/CHANGELOG.md index 82ef913743e3..9a865b74963d 100644 --- a/packages/google-cloud-container/CHANGELOG.md +++ b/packages/google-cloud-container/CHANGELOG.md @@ -4,6 +4,24 @@ [1]: https://pypi.org/project/google-cloud-container/#history +## [2.42.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-container-v2.41.0...google-cloud-container-v2.42.0) (2024-03-04) + + +### Features + +* add API to enable Provisioning Request API on existing nodepools ([43e63be](https://github.com/googleapis/google-cloud-python/commit/43e63be479ab80d4d3be2c47c3be530db4d30993)) +* add secondary boot disks field to NodePool API ([43e63be](https://github.com/googleapis/google-cloud-python/commit/43e63be479ab80d4d3be2c47c3be530db4d30993)) + + +### Bug Fixes + +* **deps:** Exclude google-auth 2.24.0 and 2.25.0 ([43e63be](https://github.com/googleapis/google-cloud-python/commit/43e63be479ab80d4d3be2c47c3be530db4d30993)) + + +### Documentation + +* Update comment for field `enable_confidential_storage` in message `google.container.v1beta1.NodeConfig` ([43e63be](https://github.com/googleapis/google-cloud-python/commit/43e63be479ab80d4d3be2c47c3be530db4d30993)) + ## [2.41.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-container-v2.40.0...google-cloud-container-v2.41.0) (2024-02-22) diff --git a/packages/google-cloud-container/google/cloud/container/gapic_version.py b/packages/google-cloud-container/google/cloud/container/gapic_version.py index 360a0d13ebdd..9e1f3252167d 100644 --- a/packages/google-cloud-container/google/cloud/container/gapic_version.py +++ b/packages/google-cloud-container/google/cloud/container/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "2.42.0" # {x-release-please-version} diff --git a/packages/google-cloud-container/google/cloud/container_v1/gapic_version.py b/packages/google-cloud-container/google/cloud/container_v1/gapic_version.py index 360a0d13ebdd..9e1f3252167d 100644 --- a/packages/google-cloud-container/google/cloud/container_v1/gapic_version.py +++ b/packages/google-cloud-container/google/cloud/container_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "2.42.0" # {x-release-please-version} diff --git a/packages/google-cloud-container/google/cloud/container_v1beta1/gapic_version.py b/packages/google-cloud-container/google/cloud/container_v1beta1/gapic_version.py index 360a0d13ebdd..9e1f3252167d 100644 --- a/packages/google-cloud-container/google/cloud/container_v1beta1/gapic_version.py +++ b/packages/google-cloud-container/google/cloud/container_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "2.42.0" # {x-release-please-version} diff --git a/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1.json b/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1.json index 477de1eee441..6477c8ef29b8 100644 --- a/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1.json +++ b/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-container", - "version": "0.1.0" + "version": "2.42.0" }, "snippets": [ { diff --git a/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1beta1.json b/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1beta1.json index afdb562b267e..f788bb23eafa 100644 --- a/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1beta1.json +++ b/packages/google-cloud-container/samples/generated_samples/snippet_metadata_google.container.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-container", - "version": "0.1.0" + "version": "2.42.0" }, "snippets": [ { diff --git a/packages/google-cloud-parallelstore/CHANGELOG.md b/packages/google-cloud-parallelstore/CHANGELOG.md index 5ddad421e08f..97fe873debd5 100644 --- a/packages/google-cloud-parallelstore/CHANGELOG.md +++ b/packages/google-cloud-parallelstore/CHANGELOG.md @@ -1 +1,10 @@ -# Changelog \ No newline at end of file +# Changelog + +## 0.1.0 (2024-03-04) + + +### Features + +* add initial files for google.cloud.parallelstore.v1beta ([#12368](https://github.com/googleapis/google-cloud-python/issues/12368)) ([db14111](https://github.com/googleapis/google-cloud-python/commit/db1411133fbdd2ee333aca125dd05996c7a95f59)) + +## Changelog diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py index 360a0d13ebdd..a7d39deb7a45 100644 --- a/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} diff --git a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py index 360a0d13ebdd..a7d39deb7a45 100644 --- a/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py +++ b/packages/google-cloud-parallelstore/google/cloud/parallelstore_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "0.1.0" # {x-release-please-version} diff --git a/packages/google-cloud-securitycenter/CHANGELOG.md b/packages/google-cloud-securitycenter/CHANGELOG.md index 04fe527f5b22..f62e5728bf96 100644 --- a/packages/google-cloud-securitycenter/CHANGELOG.md +++ b/packages/google-cloud-securitycenter/CHANGELOG.md @@ -4,6 +4,20 @@ [1]: https://pypi.org/project/google-cloud-securitycenter/#history +## [1.28.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-securitycenter-v1.27.0...google-cloud-securitycenter-v1.28.0) (2024-03-04) + + +### Features + +* Add container.create_time, vulnerability.offending_package, vulnerability.fixed_package, vulnerability.security_bulletin, vulnerability.cve.impact, vulnerability.cve.exploitation_activity, vulnerability.cve.observed_in_the_wild, vulnerability.cve.zero_day to finding's list of attributes ([4450f4c](https://github.com/googleapis/google-cloud-python/commit/4450f4ce787d11cfa11934dbd2acfe194474ca32)) +* Add load balancer, log entry, org policy, database.version, exfiltration.total_exfiltrated_bytes, file.disk_path, indicator.signature_type, and kubernetes.objects to finding's list of attributes ([4450f4c](https://github.com/googleapis/google-cloud-python/commit/4450f4ce787d11cfa11934dbd2acfe194474ca32)) +* Added security center api V2 client library ([4450f4c](https://github.com/googleapis/google-cloud-python/commit/4450f4ce787d11cfa11934dbd2acfe194474ca32)) + + +### Bug Fixes + +* **deps:** Exclude google-auth 2.24.0 and 2.25.0 ([4450f4c](https://github.com/googleapis/google-cloud-python/commit/4450f4ce787d11cfa11934dbd2acfe194474ca32)) + ## [1.27.0](https://github.com/googleapis/google-cloud-python/compare/google-cloud-securitycenter-v1.26.1...google-cloud-securitycenter-v1.27.0) (2024-02-22) diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter/gapic_version.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter/gapic_version.py index 360a0d13ebdd..251e3720307c 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter/gapic_version.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "1.28.0" # {x-release-please-version} diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/gapic_version.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/gapic_version.py index 360a0d13ebdd..251e3720307c 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/gapic_version.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "1.28.0" # {x-release-please-version} diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/gapic_version.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/gapic_version.py index 360a0d13ebdd..251e3720307c 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/gapic_version.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "1.28.0" # {x-release-please-version} diff --git a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/gapic_version.py b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/gapic_version.py index 360a0d13ebdd..251e3720307c 100644 --- a/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/gapic_version.py +++ b/packages/google-cloud-securitycenter/google/cloud/securitycenter_v1p1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.0.0" # {x-release-please-version} +__version__ = "1.28.0" # {x-release-please-version} diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1.json b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1.json index 278ec40bb216..29c4a8e18158 100644 --- a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1.json +++ b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-securitycenter", - "version": "0.1.0" + "version": "1.28.0" }, "snippets": [ { diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1beta1.json b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1beta1.json index a4c1295eaf99..a73fa0244910 100644 --- a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1beta1.json +++ b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-securitycenter", - "version": "0.1.0" + "version": "1.28.0" }, "snippets": [ { diff --git a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1p1beta1.json b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1p1beta1.json index 774592ce11f7..85e69947eb4a 100644 --- a/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1p1beta1.json +++ b/packages/google-cloud-securitycenter/samples/generated_samples/snippet_metadata_google.cloud.securitycenter.v1p1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-securitycenter", - "version": "0.1.0" + "version": "1.28.0" }, "snippets": [ {