diff --git a/.github/sync-repo-settings.yml b/.github/sync-repo-settings.yml index f06747e0..808cf3c7 100644 --- a/.github/sync-repo-settings.yml +++ b/.github/sync-repo-settings.yml @@ -1,7 +1,13 @@ +# https://github.com/googleapis/repo-automation-bots/tree/master/packages/sync-repo-settings +# Rules for master branch protection branchProtectionRules: - # List of required status check contexts that must pass for commits to be accepted to matching branches. +# Identifies the protection rule pattern. Name of the branch to be protected. +# Defaults to `master` +- pattern: master requiredStatusCheckContexts: + - 'Kokoro' + - 'cla/google' + - 'Samples - Lint' - 'Samples - Python 3.6' - 'Samples - Python 3.7' - - 'Samples - Python 3.8' - - 'Samples - Lint' + - 'Samples - Python 3.8' \ No newline at end of file diff --git a/.kokoro/docs/common.cfg b/.kokoro/docs/common.cfg index 7e0eed2c..acce2765 100644 --- a/.kokoro/docs/common.cfg +++ b/.kokoro/docs/common.cfg @@ -30,7 +30,7 @@ env_vars: { env_vars: { key: "V2_STAGING_BUCKET" - value: "docs-staging-v2-staging" + value: "docs-staging-v2" } # It will upload the docker image after successful builds. diff --git a/.kokoro/samples/python3.6/common.cfg b/.kokoro/samples/python3.6/common.cfg index 9e996a7b..4c50eb39 100644 --- a/.kokoro/samples/python3.6/common.cfg +++ b/.kokoro/samples/python3.6/common.cfg @@ -13,6 +13,12 @@ env_vars: { value: "py-3.6" } +# Declare build specific Cloud project. +env_vars: { + key: "BUILD_SPECIFIC_GCLOUD_PROJECT" + value: "python-docs-samples-tests-py36" +} + env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/python-asset/.kokoro/test-samples.sh" diff --git a/.kokoro/samples/python3.7/common.cfg b/.kokoro/samples/python3.7/common.cfg index a1ab4729..f455365a 100644 --- a/.kokoro/samples/python3.7/common.cfg +++ b/.kokoro/samples/python3.7/common.cfg @@ -13,6 +13,12 @@ env_vars: { value: "py-3.7" } +# Declare build specific Cloud project. +env_vars: { + key: "BUILD_SPECIFIC_GCLOUD_PROJECT" + value: "python-docs-samples-tests-py37" +} + env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/python-asset/.kokoro/test-samples.sh" diff --git a/.kokoro/samples/python3.8/common.cfg b/.kokoro/samples/python3.8/common.cfg index 03bec5df..4dc3b3cd 100644 --- a/.kokoro/samples/python3.8/common.cfg +++ b/.kokoro/samples/python3.8/common.cfg @@ -13,6 +13,12 @@ env_vars: { value: "py-3.8" } +# Declare build specific Cloud project. +env_vars: { + key: "BUILD_SPECIFIC_GCLOUD_PROJECT" + value: "python-docs-samples-tests-py38" +} + env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/python-asset/.kokoro/test-samples.sh" diff --git a/.kokoro/test-samples.sh b/.kokoro/test-samples.sh index 5972d11e..2e2ba06f 100755 --- a/.kokoro/test-samples.sh +++ b/.kokoro/test-samples.sh @@ -28,6 +28,12 @@ if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then git checkout $LATEST_RELEASE fi +# Exit early if samples directory doesn't exist +if [ ! -d "./samples" ]; then + echo "No tests run. `./samples` not found" + exit 0 +fi + # Disable buffering, so that the logs stream through. export PYTHONUNBUFFERED=1 @@ -101,4 +107,4 @@ cd "$ROOT" # Workaround for Kokoro permissions issue: delete secrets rm testing/{test-env.sh,client-secrets.json,service-account.json} -exit "$RTN" \ No newline at end of file +exit "$RTN" diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index b3d1f602..039f4368 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,44 +1,95 @@ -# Contributor Code of Conduct +# Code of Conduct -As contributors and maintainers of this project, -and in the interest of fostering an open and welcoming community, -we pledge to respect all people who contribute through reporting issues, -posting feature requests, updating documentation, -submitting pull requests or patches, and other activities. +## Our Pledge -We are committed to making participation in this project -a harassment-free experience for everyone, -regardless of level of experience, gender, gender identity and expression, -sexual orientation, disability, personal appearance, -body size, race, ethnicity, age, religion, or nationality. +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 -* Personal attacks -* Trolling or insulting/derogatory comments -* Public or private harassment -* Publishing other's private information, -such as physical or electronic -addresses, without explicit permission -* Other unethical or unprofessional conduct. +* 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. -By adopting this Code of Conduct, -project maintainers commit themselves to fairly and consistently -applying these principles to every aspect of managing this project. -Project maintainers who do not follow or enforce the Code of Conduct -may be permanently removed from the project team. - -This code of conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. - -Instances of abusive, harassing, or otherwise unacceptable behavior -may be reported by opening an issue -or contacting one or more of the project maintainers. - -This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, -available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) +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/docs/asset_v1/types.rst b/docs/asset_v1/types.rst index cdddc7e3..750d9c16 100644 --- a/docs/asset_v1/types.rst +++ b/docs/asset_v1/types.rst @@ -3,3 +3,4 @@ Types for Google Cloud Asset v1 API .. automodule:: google.cloud.asset_v1.types :members: + :show-inheritance: diff --git a/docs/asset_v1beta1/types.rst b/docs/asset_v1beta1/types.rst index 0c8d7ee2..71ec231b 100644 --- a/docs/asset_v1beta1/types.rst +++ b/docs/asset_v1beta1/types.rst @@ -3,3 +3,4 @@ Types for Google Cloud Asset v1beta1 API .. automodule:: google.cloud.asset_v1beta1.types :members: + :show-inheritance: diff --git a/docs/asset_v1p1beta1/types.rst b/docs/asset_v1p1beta1/types.rst index 044a7358..0df91774 100644 --- a/docs/asset_v1p1beta1/types.rst +++ b/docs/asset_v1p1beta1/types.rst @@ -3,3 +3,4 @@ Types for Google Cloud Asset v1p1beta1 API .. automodule:: google.cloud.asset_v1p1beta1.types :members: + :show-inheritance: diff --git a/docs/asset_v1p2beta1/types.rst b/docs/asset_v1p2beta1/types.rst index 16ea1eeb..cfbf146e 100644 --- a/docs/asset_v1p2beta1/types.rst +++ b/docs/asset_v1p2beta1/types.rst @@ -3,3 +3,4 @@ Types for Google Cloud Asset v1p2beta1 API .. automodule:: google.cloud.asset_v1p2beta1.types :members: + :show-inheritance: diff --git a/docs/asset_v1p4beta1/types.rst b/docs/asset_v1p4beta1/types.rst index ad03a830..a91fd590 100644 --- a/docs/asset_v1p4beta1/types.rst +++ b/docs/asset_v1p4beta1/types.rst @@ -3,3 +3,4 @@ Types for Google Cloud Asset v1p4beta1 API .. automodule:: google.cloud.asset_v1p4beta1.types :members: + :show-inheritance: diff --git a/docs/asset_v1p5beta1/types.rst b/docs/asset_v1p5beta1/types.rst index eb7cc709..0d143122 100644 --- a/docs/asset_v1p5beta1/types.rst +++ b/docs/asset_v1p5beta1/types.rst @@ -3,3 +3,4 @@ Types for Google Cloud Asset v1p5beta1 API .. automodule:: google.cloud.asset_v1p5beta1.types :members: + :show-inheritance: diff --git a/docs/conf.py b/docs/conf.py index 2ebec26b..ac323243 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -345,10 +345,14 @@ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { - "python": ("http://python.readthedocs.org/en/latest/", None), - "google-auth": ("https://google-auth.readthedocs.io/en/stable", None), + "python": ("https://python.readthedocs.org/en/latest/", None), + "google-auth": ( + "https://googleapis.dev/python/google-auth/latest/index.html", + None, + ), "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None,), - "grpc": ("https://grpc.io/grpc/python/", None), + "grpc": ("https://grpc.github.io/grpc/python/", None), + "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), } diff --git a/google/cloud/asset/__init__.py b/google/cloud/asset/__init__.py index dc2dcc22..89ddcdf7 100644 --- a/google/cloud/asset/__init__.py +++ b/google/cloud/asset/__init__.py @@ -19,6 +19,12 @@ AssetServiceAsyncClient, ) from google.cloud.asset_v1.services.asset_service.client import AssetServiceClient +from google.cloud.asset_v1.types.asset_service import AnalyzeIamPolicyLongrunningRequest +from google.cloud.asset_v1.types.asset_service import ( + AnalyzeIamPolicyLongrunningResponse, +) +from google.cloud.asset_v1.types.asset_service import AnalyzeIamPolicyRequest +from google.cloud.asset_v1.types.asset_service import AnalyzeIamPolicyResponse from google.cloud.asset_v1.types.asset_service import BatchGetAssetsHistoryRequest from google.cloud.asset_v1.types.asset_service import BatchGetAssetsHistoryResponse from google.cloud.asset_v1.types.asset_service import BigQueryDestination @@ -32,6 +38,8 @@ from google.cloud.asset_v1.types.asset_service import GcsDestination from google.cloud.asset_v1.types.asset_service import GcsOutputResult from google.cloud.asset_v1.types.asset_service import GetFeedRequest +from google.cloud.asset_v1.types.asset_service import IamPolicyAnalysisOutputConfig +from google.cloud.asset_v1.types.asset_service import IamPolicyAnalysisQuery from google.cloud.asset_v1.types.asset_service import ListFeedsRequest from google.cloud.asset_v1.types.asset_service import ListFeedsResponse from google.cloud.asset_v1.types.asset_service import OutputConfig @@ -44,6 +52,8 @@ from google.cloud.asset_v1.types.asset_service import SearchAllResourcesResponse from google.cloud.asset_v1.types.asset_service import UpdateFeedRequest from google.cloud.asset_v1.types.assets import Asset +from google.cloud.asset_v1.types.assets import IamPolicyAnalysisResult +from google.cloud.asset_v1.types.assets import IamPolicyAnalysisState from google.cloud.asset_v1.types.assets import IamPolicySearchResult from google.cloud.asset_v1.types.assets import Resource from google.cloud.asset_v1.types.assets import ResourceSearchResult @@ -51,6 +61,10 @@ from google.cloud.asset_v1.types.assets import TimeWindow __all__ = ( + "AnalyzeIamPolicyLongrunningRequest", + "AnalyzeIamPolicyLongrunningResponse", + "AnalyzeIamPolicyRequest", + "AnalyzeIamPolicyResponse", "Asset", "AssetServiceAsyncClient", "AssetServiceClient", @@ -67,6 +81,10 @@ "GcsDestination", "GcsOutputResult", "GetFeedRequest", + "IamPolicyAnalysisOutputConfig", + "IamPolicyAnalysisQuery", + "IamPolicyAnalysisResult", + "IamPolicyAnalysisState", "IamPolicySearchResult", "ListFeedsRequest", "ListFeedsResponse", diff --git a/google/cloud/asset_v1/__init__.py b/google/cloud/asset_v1/__init__.py index ebc6327e..5596fcd7 100644 --- a/google/cloud/asset_v1/__init__.py +++ b/google/cloud/asset_v1/__init__.py @@ -16,6 +16,10 @@ # from .services.asset_service import AssetServiceClient +from .types.asset_service import AnalyzeIamPolicyLongrunningRequest +from .types.asset_service import AnalyzeIamPolicyLongrunningResponse +from .types.asset_service import AnalyzeIamPolicyRequest +from .types.asset_service import AnalyzeIamPolicyResponse from .types.asset_service import BatchGetAssetsHistoryRequest from .types.asset_service import BatchGetAssetsHistoryResponse from .types.asset_service import BigQueryDestination @@ -29,6 +33,8 @@ from .types.asset_service import GcsDestination from .types.asset_service import GcsOutputResult from .types.asset_service import GetFeedRequest +from .types.asset_service import IamPolicyAnalysisOutputConfig +from .types.asset_service import IamPolicyAnalysisQuery from .types.asset_service import ListFeedsRequest from .types.asset_service import ListFeedsResponse from .types.asset_service import OutputConfig @@ -41,6 +47,8 @@ from .types.asset_service import SearchAllResourcesResponse from .types.asset_service import UpdateFeedRequest from .types.assets import Asset +from .types.assets import IamPolicyAnalysisResult +from .types.assets import IamPolicyAnalysisState from .types.assets import IamPolicySearchResult from .types.assets import Resource from .types.assets import ResourceSearchResult @@ -49,6 +57,10 @@ __all__ = ( + "AnalyzeIamPolicyLongrunningRequest", + "AnalyzeIamPolicyLongrunningResponse", + "AnalyzeIamPolicyRequest", + "AnalyzeIamPolicyResponse", "Asset", "BatchGetAssetsHistoryRequest", "BatchGetAssetsHistoryResponse", @@ -63,6 +75,10 @@ "GcsDestination", "GcsOutputResult", "GetFeedRequest", + "IamPolicyAnalysisOutputConfig", + "IamPolicyAnalysisQuery", + "IamPolicyAnalysisResult", + "IamPolicyAnalysisState", "IamPolicySearchResult", "ListFeedsRequest", "ListFeedsResponse", diff --git a/google/cloud/asset_v1/services/asset_service/async_client.py b/google/cloud/asset_v1/services/asset_service/async_client.py index 77ec24d2..98c58ffa 100644 --- a/google/cloud/asset_v1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1/services/asset_service/async_client.py @@ -48,12 +48,48 @@ class AssetServiceAsyncClient: DEFAULT_ENDPOINT = AssetServiceClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AssetServiceClient.DEFAULT_MTLS_ENDPOINT + asset_path = staticmethod(AssetServiceClient.asset_path) + feed_path = staticmethod(AssetServiceClient.feed_path) parse_feed_path = staticmethod(AssetServiceClient.parse_feed_path) + common_billing_account_path = staticmethod( + AssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetServiceClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(AssetServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(AssetServiceClient.parse_common_folder_path) + + common_organization_path = staticmethod(AssetServiceClient.common_organization_path) + parse_common_organization_path = staticmethod( + AssetServiceClient.parse_common_organization_path + ) + + common_project_path = staticmethod(AssetServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AssetServiceClient.parse_common_project_path + ) + + common_location_path = staticmethod(AssetServiceClient.common_location_path) + parse_common_location_path = staticmethod( + AssetServiceClient.parse_common_location_path + ) + from_service_account_file = AssetServiceClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(AssetServiceClient).get_transport_class, type(AssetServiceClient) ) @@ -295,7 +331,8 @@ async def create_feed( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + 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." @@ -372,7 +409,8 @@ async def get_feed( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + 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." @@ -453,7 +491,8 @@ async def list_feeds( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + 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." @@ -539,7 +578,8 @@ async def update_feed( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([feed]): + has_flattened_params = any([feed]) + 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." @@ -607,7 +647,8 @@ async def delete_feed( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + 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." @@ -753,7 +794,8 @@ async def search_all_resources( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([scope, query, asset_types]): + has_flattened_params = any([scope, query, asset_types]) + 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." @@ -768,8 +810,9 @@ async def search_all_resources( request.scope = scope if query is not None: request.query = query - if asset_types is not None: - request.asset_types = asset_types + + if asset_types: + request.asset_types.extend(asset_types) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -894,7 +937,8 @@ async def search_all_iam_policies( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([scope, query]): + has_flattened_params = any([scope, query]) + 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." @@ -944,6 +988,142 @@ async def search_all_iam_policies( # Done; return the response. return response + async def analyze_iam_policy( + self, + request: asset_service.AnalyzeIamPolicyRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> asset_service.AnalyzeIamPolicyResponse: + r"""Analyzes IAM policies to answer which identities have + what accesses on which resources. + + Args: + request (:class:`~.asset_service.AnalyzeIamPolicyRequest`): + The request object. A request message for + [AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy]. + + 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: + ~.asset_service.AnalyzeIamPolicyResponse: + A response message for + [AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy]. + + """ + # Create or coerce a protobuf request object. + + request = asset_service.AnalyzeIamPolicyRequest(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.analyze_iam_policy, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type(exceptions.ServiceUnavailable,), + ), + default_timeout=300.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( + (("analysis_query.scope", request.analysis_query.scope),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def analyze_iam_policy_longrunning( + self, + request: asset_service.AnalyzeIamPolicyLongrunningRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Analyzes IAM policies asynchronously to answer which identities + have what accesses on which resources, and writes the analysis + results to a Google Cloud Storage or a BigQuery destination. For + Cloud Storage destination, the output format is the JSON format + that represents a + [AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse]. + This method implements the + [google.longrunning.Operation][google.longrunning.Operation], + which allows you to track the operation status. We recommend + intervals of at least 2 seconds with exponential backoff retry + to poll the operation result. The metadata contains the request + to help callers to map responses to requests. + + Args: + request (:class:`~.asset_service.AnalyzeIamPolicyLongrunningRequest`): + The request object. A request message for + [AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning]. + + 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: + ~.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:``~.asset_service.AnalyzeIamPolicyLongrunningResponse``: + A response message for + [AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning]. + + """ + # Create or coerce a protobuf request object. + + request = asset_service.AnalyzeIamPolicyLongrunningRequest(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.analyze_iam_policy_longrunning, + 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( + (("analysis_query.scope", request.analysis_query.scope),) + ), + ) + + # 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, + asset_service.AnalyzeIamPolicyLongrunningResponse, + metadata_type=asset_service.AnalyzeIamPolicyLongrunningRequest, + ) + + # Done; return the response. + return response + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1/services/asset_service/client.py b/google/cloud/asset_v1/services/asset_service/client.py index 3dc4087f..ef31e4a0 100644 --- a/google/cloud/asset_v1/services/asset_service/client.py +++ b/google/cloud/asset_v1/services/asset_service/client.py @@ -132,6 +132,20 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._transport + + @staticmethod + def asset_path() -> str: + """Return a fully-qualified asset string.""" + return "*".format() + @staticmethod def feed_path(project: str, feed: str,) -> str: """Return a fully-qualified feed string.""" @@ -143,6 +157,65 @@ def parse_feed_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/feeds/(?P.+?)$", path) return m.groupdict() if m else {} + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return 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: + """Return 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: + """Return 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: + """Return 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: + """Return 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 {} + def __init__( self, *, @@ -178,10 +251,10 @@ def __init__( 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. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -908,8 +981,9 @@ def search_all_resources( request.scope = scope if query is not None: request.query = query - if asset_types is not None: - request.asset_types = asset_types + + if asset_types: + request.asset_types.extend(asset_types) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -1066,6 +1140,140 @@ def search_all_iam_policies( # Done; return the response. return response + def analyze_iam_policy( + self, + request: asset_service.AnalyzeIamPolicyRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> asset_service.AnalyzeIamPolicyResponse: + r"""Analyzes IAM policies to answer which identities have + what accesses on which resources. + + Args: + request (:class:`~.asset_service.AnalyzeIamPolicyRequest`): + The request object. A request message for + [AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy]. + + 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: + ~.asset_service.AnalyzeIamPolicyResponse: + A response message for + [AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy]. + + """ + # Create or coerce a protobuf request object. + + # Minor optimization to avoid making a copy if the user passes + # in a asset_service.AnalyzeIamPolicyRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, asset_service.AnalyzeIamPolicyRequest): + request = asset_service.AnalyzeIamPolicyRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.analyze_iam_policy] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("analysis_query.scope", request.analysis_query.scope),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def analyze_iam_policy_longrunning( + self, + request: asset_service.AnalyzeIamPolicyLongrunningRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Analyzes IAM policies asynchronously to answer which identities + have what accesses on which resources, and writes the analysis + results to a Google Cloud Storage or a BigQuery destination. For + Cloud Storage destination, the output format is the JSON format + that represents a + [AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse]. + This method implements the + [google.longrunning.Operation][google.longrunning.Operation], + which allows you to track the operation status. We recommend + intervals of at least 2 seconds with exponential backoff retry + to poll the operation result. The metadata contains the request + to help callers to map responses to requests. + + Args: + request (:class:`~.asset_service.AnalyzeIamPolicyLongrunningRequest`): + The request object. A request message for + [AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning]. + + 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: + ~.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:``~.asset_service.AnalyzeIamPolicyLongrunningResponse``: + A response message for + [AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning]. + + """ + # Create or coerce a protobuf request object. + + # Minor optimization to avoid making a copy if the user passes + # in a asset_service.AnalyzeIamPolicyLongrunningRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, asset_service.AnalyzeIamPolicyLongrunningRequest): + request = asset_service.AnalyzeIamPolicyLongrunningRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.analyze_iam_policy_longrunning + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("analysis_query.scope", request.analysis_query.scope),) + ), + ) + + # 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, + asset_service.AnalyzeIamPolicyLongrunningResponse, + metadata_type=asset_service.AnalyzeIamPolicyLongrunningRequest, + ) + + # Done; return the response. + return response + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1/services/asset_service/transports/base.py b/google/cloud/asset_v1/services/asset_service/transports/base.py index df8f2ab5..2440e350 100644 --- a/google/cloud/asset_v1/services/asset_service/transports/base.py +++ b/google/cloud/asset_v1/services/asset_service/transports/base.py @@ -194,6 +194,22 @@ def _prep_wrapped_messages(self, client_info): default_timeout=15.0, client_info=client_info, ), + self.analyze_iam_policy: gapic_v1.method.wrap_method( + self.analyze_iam_policy, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type(exceptions.ServiceUnavailable,), + ), + default_timeout=300.0, + client_info=client_info, + ), + self.analyze_iam_policy_longrunning: gapic_v1.method.wrap_method( + self.analyze_iam_policy_longrunning, + default_timeout=60.0, + client_info=client_info, + ), } @property @@ -294,5 +310,26 @@ def search_all_iam_policies( ]: raise NotImplementedError() + @property + def analyze_iam_policy( + self, + ) -> typing.Callable[ + [asset_service.AnalyzeIamPolicyRequest], + typing.Union[ + asset_service.AnalyzeIamPolicyResponse, + typing.Awaitable[asset_service.AnalyzeIamPolicyResponse], + ], + ]: + raise NotImplementedError() + + @property + def analyze_iam_policy_longrunning( + self, + ) -> typing.Callable[ + [asset_service.AnalyzeIamPolicyLongrunningRequest], + typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + ]: + raise NotImplementedError() + __all__ = ("AssetServiceTransport",) diff --git a/google/cloud/asset_v1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1/services/asset_service/transports/grpc.py index c7d19dcc..26d840cb 100644 --- a/google/cloud/asset_v1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1/services/asset_service/transports/grpc.py @@ -92,10 +92,10 @@ def __init__( for grpc 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're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -104,6 +104,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -111,6 +113,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -147,6 +150,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -224,12 +228,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.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 designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property @@ -514,5 +514,75 @@ def search_all_iam_policies( ) return self._stubs["search_all_iam_policies"] + @property + def analyze_iam_policy( + self, + ) -> Callable[ + [asset_service.AnalyzeIamPolicyRequest], asset_service.AnalyzeIamPolicyResponse + ]: + r"""Return a callable for the analyze iam policy method over gRPC. + + Analyzes IAM policies to answer which identities have + what accesses on which resources. + + Returns: + Callable[[~.AnalyzeIamPolicyRequest], + ~.AnalyzeIamPolicyResponse]: + 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 "analyze_iam_policy" not in self._stubs: + self._stubs["analyze_iam_policy"] = self.grpc_channel.unary_unary( + "/google.cloud.asset.v1.AssetService/AnalyzeIamPolicy", + request_serializer=asset_service.AnalyzeIamPolicyRequest.serialize, + response_deserializer=asset_service.AnalyzeIamPolicyResponse.deserialize, + ) + return self._stubs["analyze_iam_policy"] + + @property + def analyze_iam_policy_longrunning( + self, + ) -> Callable[ + [asset_service.AnalyzeIamPolicyLongrunningRequest], operations.Operation + ]: + r"""Return a callable for the analyze iam policy longrunning method over gRPC. + + Analyzes IAM policies asynchronously to answer which identities + have what accesses on which resources, and writes the analysis + results to a Google Cloud Storage or a BigQuery destination. For + Cloud Storage destination, the output format is the JSON format + that represents a + [AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse]. + This method implements the + [google.longrunning.Operation][google.longrunning.Operation], + which allows you to track the operation status. We recommend + intervals of at least 2 seconds with exponential backoff retry + to poll the operation result. The metadata contains the request + to help callers to map responses to requests. + + Returns: + Callable[[~.AnalyzeIamPolicyLongrunningRequest], + ~.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 "analyze_iam_policy_longrunning" not in self._stubs: + self._stubs[ + "analyze_iam_policy_longrunning" + ] = self.grpc_channel.unary_unary( + "/google.cloud.asset.v1.AssetService/AnalyzeIamPolicyLongrunning", + request_serializer=asset_service.AnalyzeIamPolicyLongrunningRequest.serialize, + response_deserializer=operations.Operation.FromString, + ) + return self._stubs["analyze_iam_policy_longrunning"] + __all__ = ("AssetServiceGrpcTransport",) diff --git a/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py index e8f70859..fe0ed4ff 100644 --- a/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py @@ -149,6 +149,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -156,6 +158,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -192,6 +195,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -520,5 +524,77 @@ def search_all_iam_policies( ) return self._stubs["search_all_iam_policies"] + @property + def analyze_iam_policy( + self, + ) -> Callable[ + [asset_service.AnalyzeIamPolicyRequest], + Awaitable[asset_service.AnalyzeIamPolicyResponse], + ]: + r"""Return a callable for the analyze iam policy method over gRPC. + + Analyzes IAM policies to answer which identities have + what accesses on which resources. + + Returns: + Callable[[~.AnalyzeIamPolicyRequest], + Awaitable[~.AnalyzeIamPolicyResponse]]: + 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 "analyze_iam_policy" not in self._stubs: + self._stubs["analyze_iam_policy"] = self.grpc_channel.unary_unary( + "/google.cloud.asset.v1.AssetService/AnalyzeIamPolicy", + request_serializer=asset_service.AnalyzeIamPolicyRequest.serialize, + response_deserializer=asset_service.AnalyzeIamPolicyResponse.deserialize, + ) + return self._stubs["analyze_iam_policy"] + + @property + def analyze_iam_policy_longrunning( + self, + ) -> Callable[ + [asset_service.AnalyzeIamPolicyLongrunningRequest], + Awaitable[operations.Operation], + ]: + r"""Return a callable for the analyze iam policy longrunning method over gRPC. + + Analyzes IAM policies asynchronously to answer which identities + have what accesses on which resources, and writes the analysis + results to a Google Cloud Storage or a BigQuery destination. For + Cloud Storage destination, the output format is the JSON format + that represents a + [AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse]. + This method implements the + [google.longrunning.Operation][google.longrunning.Operation], + which allows you to track the operation status. We recommend + intervals of at least 2 seconds with exponential backoff retry + to poll the operation result. The metadata contains the request + to help callers to map responses to requests. + + Returns: + Callable[[~.AnalyzeIamPolicyLongrunningRequest], + 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 "analyze_iam_policy_longrunning" not in self._stubs: + self._stubs[ + "analyze_iam_policy_longrunning" + ] = self.grpc_channel.unary_unary( + "/google.cloud.asset.v1.AssetService/AnalyzeIamPolicyLongrunning", + request_serializer=asset_service.AnalyzeIamPolicyLongrunningRequest.serialize, + response_deserializer=operations.Operation.FromString, + ) + return self._stubs["analyze_iam_policy_longrunning"] + __all__ = ("AssetServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/asset_v1/types/__init__.py b/google/cloud/asset_v1/types/__init__.py index 93e9b869..eaae81f4 100644 --- a/google/cloud/asset_v1/types/__init__.py +++ b/google/cloud/asset_v1/types/__init__.py @@ -22,6 +22,8 @@ Resource, ResourceSearchResult, IamPolicySearchResult, + IamPolicyAnalysisState, + IamPolicyAnalysisResult, ) from .asset_service import ( ExportAssetsRequest, @@ -47,6 +49,12 @@ SearchAllResourcesResponse, SearchAllIamPoliciesRequest, SearchAllIamPoliciesResponse, + IamPolicyAnalysisQuery, + AnalyzeIamPolicyRequest, + AnalyzeIamPolicyResponse, + IamPolicyAnalysisOutputConfig, + AnalyzeIamPolicyLongrunningRequest, + AnalyzeIamPolicyLongrunningResponse, ) @@ -57,6 +65,8 @@ "Resource", "ResourceSearchResult", "IamPolicySearchResult", + "IamPolicyAnalysisState", + "IamPolicyAnalysisResult", "ExportAssetsRequest", "ExportAssetsResponse", "BatchGetAssetsHistoryRequest", @@ -80,4 +90,10 @@ "SearchAllResourcesResponse", "SearchAllIamPoliciesRequest", "SearchAllIamPoliciesResponse", + "IamPolicyAnalysisQuery", + "AnalyzeIamPolicyRequest", + "AnalyzeIamPolicyResponse", + "IamPolicyAnalysisOutputConfig", + "AnalyzeIamPolicyLongrunningRequest", + "AnalyzeIamPolicyLongrunningResponse", ) diff --git a/google/cloud/asset_v1/types/asset_service.py b/google/cloud/asset_v1/types/asset_service.py index 4bb1fc31..39ad5c4e 100644 --- a/google/cloud/asset_v1/types/asset_service.py +++ b/google/cloud/asset_v1/types/asset_service.py @@ -19,6 +19,7 @@ from google.cloud.asset_v1.types import assets as gca_assets +from google.protobuf import duration_pb2 as duration # type: ignore from google.protobuf import field_mask_pb2 as field_mask # type: ignore from google.protobuf import timestamp_pb2 as timestamp # type: ignore from google.type import expr_pb2 as expr # type: ignore @@ -51,6 +52,12 @@ "SearchAllResourcesResponse", "SearchAllIamPoliciesRequest", "SearchAllIamPoliciesResponse", + "IamPolicyAnalysisQuery", + "AnalyzeIamPolicyRequest", + "AnalyzeIamPolicyResponse", + "IamPolicyAnalysisOutputConfig", + "AnalyzeIamPolicyLongrunningRequest", + "AnalyzeIamPolicyLongrunningResponse", }, ) @@ -62,6 +69,7 @@ class ContentType(proto.Enum): IAM_POLICY = 2 ORG_POLICY = 4 ACCESS_POLICY = 5 + OS_INVENTORY = 6 class ExportAssetsRequest(proto.Message): @@ -525,7 +533,7 @@ class FeedOutputConfig(proto.Message): """ pubsub_destination = proto.Field( - proto.MESSAGE, number=1, oneof="destination", message=PubsubDestination, + proto.MESSAGE, number=1, oneof="destination", message="PubsubDestination", ) @@ -598,7 +606,9 @@ class Feed(proto.Message): content_type = proto.Field(proto.ENUM, number=4, enum="ContentType",) - feed_output_config = proto.Field(proto.MESSAGE, number=5, message=FeedOutputConfig,) + feed_output_config = proto.Field( + proto.MESSAGE, number=5, message="FeedOutputConfig", + ) condition = proto.Field(proto.MESSAGE, number=6, message=expr.Expr,) @@ -825,4 +835,426 @@ def raw_page(self): next_page_token = proto.Field(proto.STRING, number=2) +class IamPolicyAnalysisQuery(proto.Message): + r"""IAM policy analysis query message. + + Attributes: + scope (str): + Required. The relative name of the root asset. Only + resources and IAM policies within the scope will be + analyzed. + + This can only be an organization number (such as + "organizations/123"), a folder number (such as + "folders/123"), a project ID (such as + "projects/my-project-id"), or a project number (such as + "projects/12345"). + + To know how to get organization id, visit + `here `__. + + To know how to get folder or project id, visit + `here `__. + resource_selector (~.asset_service.IamPolicyAnalysisQuery.ResourceSelector): + Optional. Specifies a resource for analysis. + identity_selector (~.asset_service.IamPolicyAnalysisQuery.IdentitySelector): + Optional. Specifies an identity for analysis. + access_selector (~.asset_service.IamPolicyAnalysisQuery.AccessSelector): + Optional. Specifies roles or permissions for + analysis. This is optional. + options (~.asset_service.IamPolicyAnalysisQuery.Options): + Optional. The query options. + """ + + class ResourceSelector(proto.Message): + r"""Specifies the resource to analyze for access policies, which + may be set directly on the resource, or on ancestors such as + organizations, folders or projects. + + Attributes: + full_resource_name (str): + Required. The [full resource name] + (https://cloud.google.com/asset-inventory/docs/resource-name-format) + of a resource of `supported resource + types `__. + """ + + full_resource_name = proto.Field(proto.STRING, number=1) + + class IdentitySelector(proto.Message): + r"""Specifies an identity for which to determine resource access, + based on roles assigned either directly to them or to the groups + they belong to, directly or indirectly. + + Attributes: + identity (str): + Required. The identity appear in the form of members in `IAM + policy + binding `__. + + The examples of supported forms are: + "user:mike@example.com", "group:admins@example.com", + "domain:google.com", + "serviceAccount:my-project-id@appspot.gserviceaccount.com". + + Notice that wildcard characters (such as \* and ?) are not + supported. You must give a specific identity. + """ + + identity = proto.Field(proto.STRING, number=1) + + class AccessSelector(proto.Message): + r"""Specifies roles and/or permissions to analyze, to determine + both the identities possessing them and the resources they + control. If multiple values are specified, results will include + roles or permissions matching any of them. The total number of + roles and permissions should be equal or less than 10. + + Attributes: + roles (Sequence[str]): + Optional. The roles to appear in result. + permissions (Sequence[str]): + Optional. The permissions to appear in + result. + """ + + roles = proto.RepeatedField(proto.STRING, number=1) + + permissions = proto.RepeatedField(proto.STRING, number=2) + + class Options(proto.Message): + r"""Contains query options. + + Attributes: + expand_groups (bool): + Optional. If true, the identities section of the result will + expand any Google groups appearing in an IAM policy binding. + + If + [IamPolicyAnalysisQuery.identity_selector][google.cloud.asset.v1.IamPolicyAnalysisQuery.identity_selector] + is specified, the identity in the result will be determined + by the selector, and this flag is not allowed to set. + + Default is false. + expand_roles (bool): + Optional. If true, the access section of result will expand + any roles appearing in IAM policy bindings to include their + permissions. + + If + [IamPolicyAnalysisQuery.access_selector][google.cloud.asset.v1.IamPolicyAnalysisQuery.access_selector] + is specified, the access section of the result will be + determined by the selector, and this flag is not allowed to + set. + + Default is false. + expand_resources (bool): + Optional. If true and + [IamPolicyAnalysisQuery.resource_selector][google.cloud.asset.v1.IamPolicyAnalysisQuery.resource_selector] + is not specified, the resource section of the result will + expand any resource attached to an IAM policy to include + resources lower in the resource hierarchy. + + For example, if the request analyzes for which resources + user A has permission P, and the results include an IAM + policy with P on a GCP folder, the results will also include + resources in that folder with permission P. + + If true and + [IamPolicyAnalysisQuery.resource_selector][google.cloud.asset.v1.IamPolicyAnalysisQuery.resource_selector] + is specified, the resource section of the result will expand + the specified resource to include resources lower in the + resource hierarchy. Only project or lower resources are + supported. Folder and organization resource cannot be used + together with this option. + + For example, if the request analyzes for which users have + permission P on a GCP project with this option enabled, the + results will include all users who have permission P on that + project or any lower resource. + + Default is false. + output_resource_edges (bool): + Optional. If true, the result will output + resource edges, starting from the policy + attached resource, to any expanded resources. + Default is false. + output_group_edges (bool): + Optional. If true, the result will output + group identity edges, starting from the + binding's group members, to any expanded + identities. Default is false. + analyze_service_account_impersonation (bool): + Optional. If true, the response will include access analysis + from identities to resources via service account + impersonation. This is a very expensive operation, because + many derived queries will be executed. We highly recommend + you use + [AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning] + rpc instead. + + For example, if the request analyzes for which resources + user A has permission P, and there's an IAM policy states + user A has iam.serviceAccounts.getAccessToken permission to + a service account SA, and there's another IAM policy states + service account SA has permission P to a GCP folder F, then + user A potentially has access to the GCP folder F. And those + advanced analysis results will be included in + [AnalyzeIamPolicyResponse.service_account_impersonation_analysis][google.cloud.asset.v1.AnalyzeIamPolicyResponse.service_account_impersonation_analysis]. + + Another example, if the request analyzes for who has + permission P to a GCP folder F, and there's an IAM policy + states user A has iam.serviceAccounts.actAs permission to a + service account SA, and there's another IAM policy states + service account SA has permission P to the GCP folder F, + then user A potentially has access to the GCP folder F. And + those advanced analysis results will be included in + [AnalyzeIamPolicyResponse.service_account_impersonation_analysis][google.cloud.asset.v1.AnalyzeIamPolicyResponse.service_account_impersonation_analysis]. + + Default is false. + """ + + expand_groups = proto.Field(proto.BOOL, number=1) + + expand_roles = proto.Field(proto.BOOL, number=2) + + expand_resources = proto.Field(proto.BOOL, number=3) + + output_resource_edges = proto.Field(proto.BOOL, number=4) + + output_group_edges = proto.Field(proto.BOOL, number=5) + + analyze_service_account_impersonation = proto.Field(proto.BOOL, number=6) + + scope = proto.Field(proto.STRING, number=1) + + resource_selector = proto.Field(proto.MESSAGE, number=2, message=ResourceSelector,) + + identity_selector = proto.Field(proto.MESSAGE, number=3, message=IdentitySelector,) + + access_selector = proto.Field(proto.MESSAGE, number=4, message=AccessSelector,) + + options = proto.Field(proto.MESSAGE, number=5, message=Options,) + + +class AnalyzeIamPolicyRequest(proto.Message): + r"""A request message for + [AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy]. + + Attributes: + analysis_query (~.asset_service.IamPolicyAnalysisQuery): + Required. The request query. + execution_timeout (~.duration.Duration): + Optional. Amount of time executable has to complete. See + JSON representation of + `Duration `__. + + If this field is set with a value less than the RPC + deadline, and the execution of your query hasn't finished in + the specified execution timeout, you will get a response + with partial result. Otherwise, your query's execution will + continue until the RPC deadline. If it's not finished until + then, you will get a DEADLINE_EXCEEDED error. + + Default is empty. + """ + + analysis_query = proto.Field( + proto.MESSAGE, number=1, message="IamPolicyAnalysisQuery", + ) + + execution_timeout = proto.Field(proto.MESSAGE, number=2, message=duration.Duration,) + + +class AnalyzeIamPolicyResponse(proto.Message): + r"""A response message for + [AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy]. + + Attributes: + main_analysis (~.asset_service.AnalyzeIamPolicyResponse.IamPolicyAnalysis): + The main analysis that matches the original + request. + service_account_impersonation_analysis (Sequence[~.asset_service.AnalyzeIamPolicyResponse.IamPolicyAnalysis]): + The service account impersonation analysis if + [AnalyzeIamPolicyRequest.analyze_service_account_impersonation][] + is enabled. + fully_explored (bool): + Represents whether all entries in the + [main_analysis][google.cloud.asset.v1.AnalyzeIamPolicyResponse.main_analysis] + and + [service_account_impersonation_analysis][google.cloud.asset.v1.AnalyzeIamPolicyResponse.service_account_impersonation_analysis] + have been fully explored to answer the query in the request. + """ + + class IamPolicyAnalysis(proto.Message): + r"""An analysis message to group the query and results. + + Attributes: + analysis_query (~.asset_service.IamPolicyAnalysisQuery): + The analysis query. + analysis_results (Sequence[~.gca_assets.IamPolicyAnalysisResult]): + A list of + [IamPolicyAnalysisResult][google.cloud.asset.v1.IamPolicyAnalysisResult] + that matches the analysis query, or empty if no result is + found. + fully_explored (bool): + Represents whether all entries in the + [analysis_results][google.cloud.asset.v1.AnalyzeIamPolicyResponse.IamPolicyAnalysis.analysis_results] + have been fully explored to answer the query. + non_critical_errors (Sequence[~.gca_assets.IamPolicyAnalysisState]): + A list of non-critical errors happened during + the query handling. + """ + + analysis_query = proto.Field( + proto.MESSAGE, number=1, message="IamPolicyAnalysisQuery", + ) + + analysis_results = proto.RepeatedField( + proto.MESSAGE, number=2, message=gca_assets.IamPolicyAnalysisResult, + ) + + fully_explored = proto.Field(proto.BOOL, number=3) + + non_critical_errors = proto.RepeatedField( + proto.MESSAGE, number=5, message=gca_assets.IamPolicyAnalysisState, + ) + + main_analysis = proto.Field(proto.MESSAGE, number=1, message=IamPolicyAnalysis,) + + service_account_impersonation_analysis = proto.RepeatedField( + proto.MESSAGE, number=2, message=IamPolicyAnalysis, + ) + + fully_explored = proto.Field(proto.BOOL, number=3) + + +class IamPolicyAnalysisOutputConfig(proto.Message): + r"""Output configuration for export IAM policy analysis + destination. + + Attributes: + gcs_destination (~.asset_service.IamPolicyAnalysisOutputConfig.GcsDestination): + Destination on Cloud Storage. + bigquery_destination (~.asset_service.IamPolicyAnalysisOutputConfig.BigQueryDestination): + Destination on BigQuery. + """ + + class GcsDestination(proto.Message): + r"""A Cloud Storage location. + + Attributes: + uri (str): + Required. The uri of the Cloud Storage object. It's the same + uri that is used by gsutil. For example: + "gs://bucket_name/object_name". See [Quickstart: Using the + gsutil tool] + (https://cloud.google.com/storage/docs/quickstart-gsutil) + for examples. + """ + + uri = proto.Field(proto.STRING, number=1) + + class BigQueryDestination(proto.Message): + r"""A BigQuery destination. + + Attributes: + dataset (str): + Required. The BigQuery dataset in format + "projects/projectId/datasets/datasetId", to which the + analysis results should be exported. If this dataset does + not exist, the export call will return an INVALID_ARGUMENT + error. + table_prefix (str): + Required. The prefix of the BigQuery tables to which the + analysis results will be written. Tables will be created + based on this table_prefix if not exist: + + - _analysis table will contain export + operation's metadata. + - _analysis_result will contain all the + [IamPolicyAnalysisResult][google.cloud.asset.v1.IamPolicyAnalysisResult]. + When [partition_key] is specified, both tables will be + partitioned based on the [partition_key]. + partition_key (~.asset_service.IamPolicyAnalysisOutputConfig.BigQueryDestination.PartitionKey): + The partition key for BigQuery partitioned + table. + write_disposition (str): + Optional. Specifies the action that occurs if the + destination table or partition already exists. The following + values are supported: + + - WRITE_TRUNCATE: If the table or partition already exists, + BigQuery overwrites the entire table or all the + partitions data. + - WRITE_APPEND: If the table or partition already exists, + BigQuery appends the data to the table or the latest + partition. + - WRITE_EMPTY: If the table already exists and contains + data, an error is returned. + + The default value is WRITE_APPEND. Each action is atomic and + only occurs if BigQuery is able to complete the job + successfully. Details are at + https://cloud.google.com/bigquery/docs/loading-data-local#appending_to_or_overwriting_a_table_using_a_local_file. + """ + + class PartitionKey(proto.Enum): + r"""This enum determines the partition key column for the + bigquery tables. Partitioning can improve query performance and + reduce query cost by filtering partitions. Refer to + https://cloud.google.com/bigquery/docs/partitioned-tables for + details. + """ + PARTITION_KEY_UNSPECIFIED = 0 + REQUEST_TIME = 1 + + dataset = proto.Field(proto.STRING, number=1) + + table_prefix = proto.Field(proto.STRING, number=2) + + partition_key = proto.Field( + proto.ENUM, + number=3, + enum="IamPolicyAnalysisOutputConfig.BigQueryDestination.PartitionKey", + ) + + write_disposition = proto.Field(proto.STRING, number=4) + + gcs_destination = proto.Field( + proto.MESSAGE, number=1, oneof="destination", message=GcsDestination, + ) + + bigquery_destination = proto.Field( + proto.MESSAGE, number=2, oneof="destination", message=BigQueryDestination, + ) + + +class AnalyzeIamPolicyLongrunningRequest(proto.Message): + r"""A request message for + [AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning]. + + Attributes: + analysis_query (~.asset_service.IamPolicyAnalysisQuery): + Required. The request query. + output_config (~.asset_service.IamPolicyAnalysisOutputConfig): + Required. Output configuration indicating + where the results will be output to. + """ + + analysis_query = proto.Field( + proto.MESSAGE, number=1, message="IamPolicyAnalysisQuery", + ) + + output_config = proto.Field( + proto.MESSAGE, number=2, message="IamPolicyAnalysisOutputConfig", + ) + + +class AnalyzeIamPolicyLongrunningResponse(proto.Message): + r"""A response message for + [AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning]. + """ + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/asset_v1/types/assets.py b/google/cloud/asset_v1/types/assets.py index 95d21e50..fbbac89c 100644 --- a/google/cloud/asset_v1/types/assets.py +++ b/google/cloud/asset_v1/types/assets.py @@ -19,12 +19,14 @@ from google.cloud.orgpolicy.v1 import orgpolicy_pb2 as orgpolicy # type: ignore +from google.cloud.osconfig_v1 import Inventory # type: ignore from google.iam.v1 import policy_pb2 as gi_policy # type: ignore from google.identity.accesscontextmanager.v1 import access_level_pb2 as gia_access_level # type: ignore from google.identity.accesscontextmanager.v1 import access_policy_pb2 as gia_access_policy # type: ignore from google.identity.accesscontextmanager.v1 import service_perimeter_pb2 as gia_service_perimeter # type: ignore from google.protobuf import struct_pb2 as struct # type: ignore from google.protobuf import timestamp_pb2 as timestamp # type: ignore +from google.rpc import code_pb2 as gr_code # type: ignore __protobuf__ = proto.module( @@ -36,6 +38,8 @@ "Resource", "ResourceSearchResult", "IamPolicySearchResult", + "IamPolicyAnalysisState", + "IamPolicyAnalysisResult", }, ) @@ -153,6 +157,11 @@ class Asset(proto.Message): service_perimeter (~.gia_service_perimeter.ServicePerimeter): Please also refer to the `service perimeter user guide `__. + os_inventory (~.inventory.Inventory): + A representation of runtime OS Inventory information. See + `this + topic `__ + for more information. ancestors (Sequence[str]): The ancestry path of an asset in Google Cloud `resource hierarchy `__, @@ -199,6 +208,8 @@ class Asset(proto.Message): message=gia_service_perimeter.ServicePerimeter, ) + os_inventory = proto.Field(proto.MESSAGE, number=12, message=Inventory,) + ancestors = proto.RepeatedField(proto.STRING, number=10) @@ -490,4 +501,242 @@ class Permissions(proto.Message): explanation = proto.Field(proto.MESSAGE, number=4, message=Explanation,) +class IamPolicyAnalysisState(proto.Message): + r"""Represents the detailed state of an entity under analysis, + such as a resource, an identity or an access. + + Attributes: + code (~.gr_code.Code): + The Google standard error code that best describes the + state. For example: + + - OK means the analysis on this entity has been + successfully finished; + - PERMISSION_DENIED means an access denied error is + encountered; + - DEADLINE_EXCEEDED means the analysis on this entity + hasn't been started in time; + cause (str): + The human-readable description of the cause + of failure. + """ + + code = proto.Field(proto.ENUM, number=1, enum=gr_code.Code,) + + cause = proto.Field(proto.STRING, number=2) + + +class IamPolicyAnalysisResult(proto.Message): + r"""IAM Policy analysis result, consisting of one IAM policy + binding and derived access control lists. + + Attributes: + attached_resource_full_name (str): + The `full resource + name `__ + of the resource to which the + [iam_binding][google.cloud.asset.v1.IamPolicyAnalysisResult.iam_binding] + policy attaches. + iam_binding (~.gi_policy.Binding): + The Cloud IAM policy binding under analysis. + access_control_lists (Sequence[~.assets.IamPolicyAnalysisResult.AccessControlList]): + The access control lists derived from the + [iam_binding][google.cloud.asset.v1.IamPolicyAnalysisResult.iam_binding] + that match or potentially match resource and access + selectors specified in the request. + identity_list (~.assets.IamPolicyAnalysisResult.IdentityList): + The identity list derived from members of the + [iam_binding][google.cloud.asset.v1.IamPolicyAnalysisResult.iam_binding] + that match or potentially match identity selector specified + in the request. + fully_explored (bool): + Represents whether all analyses on the + [iam_binding][google.cloud.asset.v1.IamPolicyAnalysisResult.iam_binding] + have successfully finished. + """ + + class Resource(proto.Message): + r"""A Google Cloud resource under analysis. + + Attributes: + full_resource_name (str): + The `full resource + name `__ + analysis_state (~.assets.IamPolicyAnalysisState): + The analysis state of this resource. + """ + + full_resource_name = proto.Field(proto.STRING, number=1) + + analysis_state = proto.Field( + proto.MESSAGE, number=2, message="IamPolicyAnalysisState", + ) + + class Access(proto.Message): + r"""An IAM role or permission under analysis. + + Attributes: + role (str): + The role. + permission (str): + The permission. + analysis_state (~.assets.IamPolicyAnalysisState): + The analysis state of this access. + """ + + role = proto.Field(proto.STRING, number=1, oneof="oneof_access") + + permission = proto.Field(proto.STRING, number=2, oneof="oneof_access") + + analysis_state = proto.Field( + proto.MESSAGE, number=3, message="IamPolicyAnalysisState", + ) + + class Identity(proto.Message): + r"""An identity under analysis. + + Attributes: + name (str): + The identity name in any form of members appear in `IAM + policy + binding `__, + such as: + + - user:foo@google.com + - group:group1@google.com + - serviceAccount:s1@prj1.iam.gserviceaccount.com + - projectOwner:some_project_id + - domain:google.com + - allUsers + - etc. + analysis_state (~.assets.IamPolicyAnalysisState): + The analysis state of this identity. + """ + + name = proto.Field(proto.STRING, number=1) + + analysis_state = proto.Field( + proto.MESSAGE, number=2, message="IamPolicyAnalysisState", + ) + + class Edge(proto.Message): + r"""A directional edge. + + Attributes: + source_node (str): + The source node of the edge. For example, it + could be a full resource name for a resource + node or an email of an identity. + target_node (str): + The target node of the edge. For example, it + could be a full resource name for a resource + node or an email of an identity. + """ + + source_node = proto.Field(proto.STRING, number=1) + + target_node = proto.Field(proto.STRING, number=2) + + class AccessControlList(proto.Message): + r"""An access control list, derived from the above IAM policy binding, + which contains a set of resources and accesses. May include one item + from each set to compose an access control entry. + + NOTICE that there could be multiple access control lists for one IAM + policy binding. The access control lists are created based on + resource and access combinations. + + For example, assume we have the following cases in one IAM policy + binding: + + - Permission P1 and P2 apply to resource R1 and R2; + - Permission P3 applies to resource R2 and R3; + + This will result in the following access control lists: + + - AccessControlList 1: [R1, R2], [P1, P2] + - AccessControlList 2: [R2, R3], [P3] + + Attributes: + resources (Sequence[~.assets.IamPolicyAnalysisResult.Resource]): + The resources that match one of the following conditions: + + - The resource_selector, if it is specified in request; + - Otherwise, resources reachable from the policy attached + resource. + accesses (Sequence[~.assets.IamPolicyAnalysisResult.Access]): + The accesses that match one of the following conditions: + + - The access_selector, if it is specified in request; + - Otherwise, access specifiers reachable from the policy + binding's role. + resource_edges (Sequence[~.assets.IamPolicyAnalysisResult.Edge]): + Resource edges of the graph starting from the policy + attached resource to any descendant resources. The + [Edge.source_node][google.cloud.asset.v1.IamPolicyAnalysisResult.Edge.source_node] + contains the full resource name of a parent resource and + [Edge.target_node][google.cloud.asset.v1.IamPolicyAnalysisResult.Edge.target_node] + contains the full resource name of a child resource. This + field is present only if the output_resource_edges option is + enabled in request. + """ + + resources = proto.RepeatedField( + proto.MESSAGE, number=1, message="IamPolicyAnalysisResult.Resource", + ) + + accesses = proto.RepeatedField( + proto.MESSAGE, number=2, message="IamPolicyAnalysisResult.Access", + ) + + resource_edges = proto.RepeatedField( + proto.MESSAGE, number=3, message="IamPolicyAnalysisResult.Edge", + ) + + class IdentityList(proto.Message): + r"""The identities and group edges. + + Attributes: + identities (Sequence[~.assets.IamPolicyAnalysisResult.Identity]): + Only the identities that match one of the following + conditions will be presented: + + - The identity_selector, if it is specified in request; + - Otherwise, identities reachable from the policy binding's + members. + group_edges (Sequence[~.assets.IamPolicyAnalysisResult.Edge]): + Group identity edges of the graph starting from the + binding's group members to any node of the + [identities][google.cloud.asset.v1.IamPolicyAnalysisResult.IdentityList.identities]. + The + [Edge.source_node][google.cloud.asset.v1.IamPolicyAnalysisResult.Edge.source_node] + contains a group, such as ``group:parent@google.com``. The + [Edge.target_node][google.cloud.asset.v1.IamPolicyAnalysisResult.Edge.target_node] + contains a member of the group, such as + ``group:child@google.com`` or ``user:foo@google.com``. This + field is present only if the output_group_edges option is + enabled in request. + """ + + identities = proto.RepeatedField( + proto.MESSAGE, number=1, message="IamPolicyAnalysisResult.Identity", + ) + + group_edges = proto.RepeatedField( + proto.MESSAGE, number=2, message="IamPolicyAnalysisResult.Edge", + ) + + attached_resource_full_name = proto.Field(proto.STRING, number=1) + + iam_binding = proto.Field(proto.MESSAGE, number=2, message=gi_policy.Binding,) + + access_control_lists = proto.RepeatedField( + proto.MESSAGE, number=3, message=AccessControlList, + ) + + identity_list = proto.Field(proto.MESSAGE, number=4, message=IdentityList,) + + fully_explored = proto.Field(proto.BOOL, number=5) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/asset_v1beta1/services/asset_service/async_client.py b/google/cloud/asset_v1beta1/services/asset_service/async_client.py index 99067a97..225dd6d4 100644 --- a/google/cloud/asset_v1beta1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1beta1/services/asset_service/async_client.py @@ -46,9 +46,45 @@ class AssetServiceAsyncClient: DEFAULT_ENDPOINT = AssetServiceClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AssetServiceClient.DEFAULT_MTLS_ENDPOINT + asset_path = staticmethod(AssetServiceClient.asset_path) + + common_billing_account_path = staticmethod( + AssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetServiceClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(AssetServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(AssetServiceClient.parse_common_folder_path) + + common_organization_path = staticmethod(AssetServiceClient.common_organization_path) + parse_common_organization_path = staticmethod( + AssetServiceClient.parse_common_organization_path + ) + + common_project_path = staticmethod(AssetServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AssetServiceClient.parse_common_project_path + ) + + common_location_path = staticmethod(AssetServiceClient.common_location_path) + parse_common_location_path = staticmethod( + AssetServiceClient.parse_common_location_path + ) + from_service_account_file = AssetServiceClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(AssetServiceClient).get_transport_class, type(AssetServiceClient) ) @@ -213,7 +249,7 @@ async def batch_get_assets_history( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=60.0, diff --git a/google/cloud/asset_v1beta1/services/asset_service/client.py b/google/cloud/asset_v1beta1/services/asset_service/client.py index 6959cefd..52a01dcf 100644 --- a/google/cloud/asset_v1beta1/services/asset_service/client.py +++ b/google/cloud/asset_v1beta1/services/asset_service/client.py @@ -130,6 +130,79 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._transport + + @staticmethod + def asset_path() -> str: + """Return a fully-qualified asset string.""" + return "*".format() + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return 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: + """Return 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: + """Return 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: + """Return 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: + """Return 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 {} + def __init__( self, *, @@ -165,10 +238,10 @@ def __init__( 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. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: diff --git a/google/cloud/asset_v1beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1beta1/services/asset_service/transports/base.py index 835f8d06..98418226 100644 --- a/google/cloud/asset_v1beta1/services/asset_service/transports/base.py +++ b/google/cloud/asset_v1beta1/services/asset_service/transports/base.py @@ -116,7 +116,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=60.0, diff --git a/google/cloud/asset_v1beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1beta1/services/asset_service/transports/grpc.py index c97bf231..9a5eb9da 100644 --- a/google/cloud/asset_v1beta1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1beta1/services/asset_service/transports/grpc.py @@ -91,10 +91,10 @@ def __init__( for grpc 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're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -103,6 +103,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -110,6 +112,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -146,6 +149,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -223,12 +227,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.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 designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/asset_v1beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1beta1/services/asset_service/transports/grpc_asyncio.py index eae291d7..0331ade0 100644 --- a/google/cloud/asset_v1beta1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1beta1/services/asset_service/transports/grpc_asyncio.py @@ -148,6 +148,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -155,6 +157,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -191,6 +194,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py index 950fd5b1..5656381e 100644 --- a/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py @@ -45,9 +45,43 @@ class AssetServiceAsyncClient: DEFAULT_ENDPOINT = AssetServiceClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AssetServiceClient.DEFAULT_MTLS_ENDPOINT + common_billing_account_path = staticmethod( + AssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetServiceClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(AssetServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(AssetServiceClient.parse_common_folder_path) + + common_organization_path = staticmethod(AssetServiceClient.common_organization_path) + parse_common_organization_path = staticmethod( + AssetServiceClient.parse_common_organization_path + ) + + common_project_path = staticmethod(AssetServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AssetServiceClient.parse_common_project_path + ) + + common_location_path = staticmethod(AssetServiceClient.common_location_path) + parse_common_location_path = staticmethod( + AssetServiceClient.parse_common_location_path + ) + from_service_account_file = AssetServiceClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(AssetServiceClient).get_transport_class, type(AssetServiceClient) ) @@ -165,7 +199,8 @@ async def search_all_resources( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([scope, query, asset_types]): + has_flattened_params = any([scope, query, asset_types]) + 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." @@ -180,8 +215,9 @@ async def search_all_resources( request.scope = scope if query is not None: request.query = query - if asset_types is not None: - request.asset_types = asset_types + + if asset_types: + request.asset_types.extend(asset_types) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -192,7 +228,7 @@ async def search_all_resources( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=15.0, @@ -277,7 +313,8 @@ async def search_all_iam_policies( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([scope, query]): + has_flattened_params = any([scope, query]) + 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." @@ -302,7 +339,7 @@ async def search_all_iam_policies( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=15.0, diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/client.py b/google/cloud/asset_v1p1beta1/services/asset_service/client.py index f84a12f7..416ec43a 100644 --- a/google/cloud/asset_v1p1beta1/services/asset_service/client.py +++ b/google/cloud/asset_v1p1beta1/services/asset_service/client.py @@ -129,6 +129,74 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return 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: + """Return 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: + """Return 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: + """Return 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: + """Return 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 {} + def __init__( self, *, @@ -164,10 +232,10 @@ def __init__( 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. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -332,8 +400,9 @@ def search_all_resources( request.scope = scope if query is not None: request.query = query - if asset_types is not None: - request.asset_types = asset_types + + if asset_types: + request.asset_types.extend(asset_types) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py index f5ce5bb5..f43cae3f 100644 --- a/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py +++ b/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py @@ -111,7 +111,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=15.0, @@ -124,7 +124,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=15.0, diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py index 96da85b0..42bcaa91 100644 --- a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py @@ -89,10 +89,10 @@ def __init__( for grpc 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're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -101,6 +101,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -108,6 +110,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -144,6 +147,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -221,12 +225,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.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 designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py index d947273e..8f42e007 100644 --- a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py @@ -146,6 +146,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -153,6 +155,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -189,6 +192,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py index 44fe88ac..11230e08 100644 --- a/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py @@ -46,9 +46,43 @@ class AssetServiceAsyncClient: feed_path = staticmethod(AssetServiceClient.feed_path) parse_feed_path = staticmethod(AssetServiceClient.parse_feed_path) + common_billing_account_path = staticmethod( + AssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetServiceClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(AssetServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(AssetServiceClient.parse_common_folder_path) + + common_organization_path = staticmethod(AssetServiceClient.common_organization_path) + parse_common_organization_path = staticmethod( + AssetServiceClient.parse_common_organization_path + ) + + common_project_path = staticmethod(AssetServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AssetServiceClient.parse_common_project_path + ) + + common_location_path = staticmethod(AssetServiceClient.common_location_path) + parse_common_location_path = staticmethod( + AssetServiceClient.parse_common_location_path + ) + from_service_account_file = AssetServiceClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(AssetServiceClient).get_transport_class, type(AssetServiceClient) ) @@ -151,7 +185,8 @@ async def create_feed( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + 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." @@ -228,7 +263,8 @@ async def get_feed( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + 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." @@ -309,7 +345,8 @@ async def list_feeds( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent]): + 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." @@ -395,7 +432,8 @@ async def update_feed( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([feed]): + has_flattened_params = any([feed]) + 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." @@ -463,7 +501,8 @@ async def delete_feed( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + 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." diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/client.py b/google/cloud/asset_v1p2beta1/services/asset_service/client.py index 9777a690..36f37947 100644 --- a/google/cloud/asset_v1p2beta1/services/asset_service/client.py +++ b/google/cloud/asset_v1p2beta1/services/asset_service/client.py @@ -127,6 +127,15 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._transport + @staticmethod def feed_path(project: str, feed: str,) -> str: """Return a fully-qualified feed string.""" @@ -138,6 +147,65 @@ def parse_feed_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/feeds/(?P.+?)$", path) return m.groupdict() if m else {} + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return 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: + """Return 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: + """Return 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: + """Return 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: + """Return 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 {} + def __init__( self, *, @@ -173,10 +241,10 @@ def __init__( 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. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py index 7b3fca43..e6b034a2 100644 --- a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py @@ -90,10 +90,10 @@ def __init__( for grpc 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're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -102,6 +102,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -109,6 +111,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -145,6 +148,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -222,12 +226,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.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 designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py index 62051653..2d7ef306 100644 --- a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py @@ -147,6 +147,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -154,6 +156,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -190,6 +193,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" diff --git a/google/cloud/asset_v1p2beta1/types/asset_service.py b/google/cloud/asset_v1p2beta1/types/asset_service.py index bd64a00a..43aa2f1a 100644 --- a/google/cloud/asset_v1p2beta1/types/asset_service.py +++ b/google/cloud/asset_v1p2beta1/types/asset_service.py @@ -205,7 +205,7 @@ class FeedOutputConfig(proto.Message): """ pubsub_destination = proto.Field( - proto.MESSAGE, number=1, oneof="destination", message=PubsubDestination, + proto.MESSAGE, number=1, oneof="destination", message="PubsubDestination", ) @@ -263,7 +263,9 @@ class Feed(proto.Message): content_type = proto.Field(proto.ENUM, number=4, enum="ContentType",) - feed_output_config = proto.Field(proto.MESSAGE, number=5, message=FeedOutputConfig,) + feed_output_config = proto.Field( + proto.MESSAGE, number=5, message="FeedOutputConfig", + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py index 42020162..f3880182 100644 --- a/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py @@ -46,9 +46,43 @@ class AssetServiceAsyncClient: DEFAULT_ENDPOINT = AssetServiceClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AssetServiceClient.DEFAULT_MTLS_ENDPOINT + common_billing_account_path = staticmethod( + AssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetServiceClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(AssetServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(AssetServiceClient.parse_common_folder_path) + + common_organization_path = staticmethod(AssetServiceClient.common_organization_path) + parse_common_organization_path = staticmethod( + AssetServiceClient.parse_common_organization_path + ) + + common_project_path = staticmethod(AssetServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AssetServiceClient.parse_common_project_path + ) + + common_location_path = staticmethod(AssetServiceClient.common_location_path) + parse_common_location_path = staticmethod( + AssetServiceClient.parse_common_location_path + ) + from_service_account_file = AssetServiceClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(AssetServiceClient).get_transport_class, type(AssetServiceClient) ) diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/client.py b/google/cloud/asset_v1p4beta1/services/asset_service/client.py index 94efec17..7fe58691 100644 --- a/google/cloud/asset_v1p4beta1/services/asset_service/client.py +++ b/google/cloud/asset_v1p4beta1/services/asset_service/client.py @@ -130,6 +130,74 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return 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: + """Return 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: + """Return 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: + """Return 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: + """Return 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 {} + def __init__( self, *, @@ -165,10 +233,10 @@ def __init__( 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. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py index 1449f6bb..981aea53 100644 --- a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py @@ -91,10 +91,10 @@ def __init__( for grpc 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're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -103,6 +103,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -110,6 +112,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -146,6 +149,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -223,12 +227,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.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 designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py index f090f104..3740eabf 100644 --- a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py @@ -148,6 +148,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -155,6 +157,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -191,6 +194,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" diff --git a/google/cloud/asset_v1p4beta1/types/asset_service.py b/google/cloud/asset_v1p4beta1/types/asset_service.py index db0a93fc..2f9285b2 100644 --- a/google/cloud/asset_v1p4beta1/types/asset_service.py +++ b/google/cloud/asset_v1p4beta1/types/asset_service.py @@ -232,7 +232,7 @@ class Options(proto.Message): ) analysis_query = proto.Field( - proto.MESSAGE, number=1, message=IamPolicyAnalysisQuery, + proto.MESSAGE, number=1, message="IamPolicyAnalysisQuery", ) options = proto.Field(proto.MESSAGE, number=2, message=Options,) @@ -280,7 +280,7 @@ class IamPolicyAnalysis(proto.Message): """ analysis_query = proto.Field( - proto.MESSAGE, number=1, message=IamPolicyAnalysisQuery, + proto.MESSAGE, number=1, message="IamPolicyAnalysisQuery", ) analysis_results = proto.RepeatedField( @@ -431,13 +431,13 @@ class Options(proto.Message): analyze_service_account_impersonation = proto.Field(proto.BOOL, number=6) analysis_query = proto.Field( - proto.MESSAGE, number=1, message=IamPolicyAnalysisQuery, + proto.MESSAGE, number=1, message="IamPolicyAnalysisQuery", ) options = proto.Field(proto.MESSAGE, number=2, message=Options,) output_config = proto.Field( - proto.MESSAGE, number=3, message=IamPolicyAnalysisOutputConfig, + proto.MESSAGE, number=3, message="IamPolicyAnalysisOutputConfig", ) @@ -453,7 +453,7 @@ class ExportIamPolicyAnalysisResponse(proto.Message): """ output_config = proto.Field( - proto.MESSAGE, number=1, message=IamPolicyAnalysisOutputConfig, + proto.MESSAGE, number=1, message="IamPolicyAnalysisOutputConfig", ) diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py index 9d8838f2..e5d56974 100644 --- a/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py @@ -45,9 +45,45 @@ class AssetServiceAsyncClient: DEFAULT_ENDPOINT = AssetServiceClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AssetServiceClient.DEFAULT_MTLS_ENDPOINT + asset_path = staticmethod(AssetServiceClient.asset_path) + + common_billing_account_path = staticmethod( + AssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetServiceClient.parse_common_billing_account_path + ) + + common_folder_path = staticmethod(AssetServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(AssetServiceClient.parse_common_folder_path) + + common_organization_path = staticmethod(AssetServiceClient.common_organization_path) + parse_common_organization_path = staticmethod( + AssetServiceClient.parse_common_organization_path + ) + + common_project_path = staticmethod(AssetServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AssetServiceClient.parse_common_project_path + ) + + common_location_path = staticmethod(AssetServiceClient.common_location_path) + parse_common_location_path = staticmethod( + AssetServiceClient.parse_common_location_path + ) + from_service_account_file = AssetServiceClient.from_service_account_file from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + get_transport_class = functools.partial( type(AssetServiceClient).get_transport_class, type(AssetServiceClient) ) @@ -142,7 +178,7 @@ async def list_assets( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=60.0, diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/client.py b/google/cloud/asset_v1p5beta1/services/asset_service/client.py index d8532be3..0ba04274 100644 --- a/google/cloud/asset_v1p5beta1/services/asset_service/client.py +++ b/google/cloud/asset_v1p5beta1/services/asset_service/client.py @@ -129,6 +129,79 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @property + def transport(self) -> AssetServiceTransport: + """Return the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._transport + + @staticmethod + def asset_path() -> str: + """Return a fully-qualified asset string.""" + return "*".format() + + @staticmethod + def common_billing_account_path(billing_account: str,) -> str: + """Return 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: + """Return 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: + """Return 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: + """Return 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: + """Return 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 {} + def __init__( self, *, @@ -164,10 +237,10 @@ def __init__( 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. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py index 6d93cb92..53bdd621 100644 --- a/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py +++ b/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py @@ -111,7 +111,7 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.ServiceUnavailable, exceptions.DeadlineExceeded, + exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), ), default_timeout=60.0, diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py index e11e653d..a0670c85 100644 --- a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py @@ -89,10 +89,10 @@ def __init__( for grpc 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're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -101,6 +101,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -108,6 +110,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -144,6 +147,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" @@ -221,12 +225,8 @@ def create_channel( @property def grpc_channel(self) -> grpc.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 designed to connect to this service. """ - # Return the channel from cache. return self._grpc_channel @property diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py index 14028cba..87abf403 100644 --- a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py @@ -146,6 +146,8 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._ssl_channel_credentials = ssl_channel_credentials + if channel: # Sanity check: Ensure that channel and credentials are not both # provided. @@ -153,6 +155,7 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel + self._ssl_channel_credentials = None elif api_mtls_endpoint: warnings.warn( "api_mtls_endpoint and client_cert_source are deprecated", @@ -189,6 +192,7 @@ def __init__( scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, ) + self._ssl_channel_credentials = ssl_credentials else: host = host if ":" in host else host + ":443" diff --git a/noxfile.py b/noxfile.py index 0132b75d..41eeb037 100644 --- a/noxfile.py +++ b/noxfile.py @@ -28,7 +28,7 @@ DEFAULT_PYTHON_VERSION = "3.8" SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"] -UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8"] +UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] @nox.session(python=DEFAULT_PYTHON_VERSION) @@ -72,16 +72,17 @@ def default(session): # Install all test dependencies, then install this package in-place. session.install("asyncmock", "pytest-asyncio") - session.install("mock", "pytest", "pytest-cov") + session.install( + "mock", "pytest", "pytest-cov", + ) session.install("-e", ".") # Run py.test against the unit tests. session.run( "py.test", "--quiet", - "--cov=google.cloud.asset", - "--cov=google.cloud", - "--cov=tests.unit", + "--cov=google/cloud", + "--cov=tests/unit", "--cov-append", "--cov-config=.coveragerc", "--cov-report=", @@ -151,7 +152,7 @@ def docs(session): """Build the docs for this library.""" session.install("-e", ".") - session.install("sphinx<3.0.0", "alabaster", "recommonmark") + session.install("sphinx", "alabaster", "recommonmark") shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) session.run( diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py index ba55d7ce..b90eef00 100644 --- a/samples/snippets/noxfile.py +++ b/samples/snippets/noxfile.py @@ -39,6 +39,10 @@ # You can opt out from the test for specific Python versions. 'ignored_versions': ["2.7"], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + 'enforce_type_hints': False, + # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string @@ -132,7 +136,10 @@ def _determine_local_import_names(start_dir): @nox.session def lint(session): - session.install("flake8", "flake8-import-order") + if not TEST_CONFIG['enforce_type_hints']: + session.install("flake8", "flake8-import-order") + else: + session.install("flake8", "flake8-import-order", "flake8-annotations") local_names = _determine_local_import_names(".") args = FLAKE8_COMMON_ARGS + [ @@ -141,8 +148,18 @@ def lint(session): "." ] session.run("flake8", *args) +# +# Black +# +@nox.session +def blacken(session): + session.install("black") + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + # # Sample Tests # @@ -201,6 +218,11 @@ def _get_repo_root(): break if Path(p / ".git").exists(): return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) p = p.parent raise Exception("Unable to detect repository root.") diff --git a/scripts/fixup_asset_v1_keywords.py b/scripts/fixup_asset_v1_keywords.py index 8c525868..b6738f86 100644 --- a/scripts/fixup_asset_v1_keywords.py +++ b/scripts/fixup_asset_v1_keywords.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2020 Google LLC @@ -40,6 +41,8 @@ def partition( class assetCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'analyze_iam_policy': ('analysis_query', 'execution_timeout', ), + 'analyze_iam_policy_longrunning': ('analysis_query', 'output_config', ), 'batch_get_assets_history': ('parent', 'asset_names', 'content_type', 'read_time_window', ), 'create_feed': ('parent', 'feed_id', 'feed', ), 'delete_feed': ('name', ), diff --git a/scripts/fixup_asset_v1beta1_keywords.py b/scripts/fixup_asset_v1beta1_keywords.py index f53578bc..e3bb7510 100644 --- a/scripts/fixup_asset_v1beta1_keywords.py +++ b/scripts/fixup_asset_v1beta1_keywords.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2020 Google LLC diff --git a/scripts/fixup_asset_v1p1beta1_keywords.py b/scripts/fixup_asset_v1p1beta1_keywords.py index d15e8ce8..125f85e7 100644 --- a/scripts/fixup_asset_v1p1beta1_keywords.py +++ b/scripts/fixup_asset_v1p1beta1_keywords.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2020 Google LLC diff --git a/scripts/fixup_asset_v1p2beta1_keywords.py b/scripts/fixup_asset_v1p2beta1_keywords.py index edf8be71..d2e7d9a4 100644 --- a/scripts/fixup_asset_v1p2beta1_keywords.py +++ b/scripts/fixup_asset_v1p2beta1_keywords.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2020 Google LLC diff --git a/scripts/fixup_asset_v1p4beta1_keywords.py b/scripts/fixup_asset_v1p4beta1_keywords.py index a422fe32..fa32405d 100644 --- a/scripts/fixup_asset_v1p4beta1_keywords.py +++ b/scripts/fixup_asset_v1p4beta1_keywords.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2020 Google LLC diff --git a/scripts/fixup_asset_v1p5beta1_keywords.py b/scripts/fixup_asset_v1p5beta1_keywords.py index da88d60e..4d718d46 100644 --- a/scripts/fixup_asset_v1p5beta1_keywords.py +++ b/scripts/fixup_asset_v1p5beta1_keywords.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2020 Google LLC diff --git a/setup.py b/setup.py index 45402f61..3f48e031 100644 --- a/setup.py +++ b/setup.py @@ -32,6 +32,7 @@ "grpc-google-iam-v1 >= 0.12.3, < 0.13dev", "google-cloud-access-context-manager >= 0.1.2, < 0.2.0dev", "google-cloud-org-policy >= 0.1.2, < 0.2.0dev", + "google-cloud-os-config >= 1.0.0, <2.0.0dev", "proto-plus >= 0.4.0", "libcst >= 0.2.5", ] diff --git a/synth.metadata b/synth.metadata index e99a8ccb..56254ce2 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,30 +3,30 @@ { "git": { "name": ".", - "remote": "https://github.com/googleapis/python-asset.git", - "sha": "113530786f16b1ae779d227619a274e97cfdcf7a" + "remote": "git@github.com:googleapis/python-asset.git", + "sha": "1f9476b6b24f471bd2d0f726bd865baf03cc4752" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "3dbeac0d54125b123c8dfd39c774b37473c36944", - "internalRef": "333159182" + "sha": "e7b8cc00065515c3768f57f19a514d8697f76ff4", + "internalRef": "343159248" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "a651c5fb763c69a921aecdd3e1d8dc51dbf20f8d" + "sha": "39b7149da4026765385403632db3c6f63db96b2c" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "a651c5fb763c69a921aecdd3e1d8dc51dbf20f8d" + "sha": "39b7149da4026765385403632db3c6f63db96b2c" } } ], @@ -85,187 +85,5 @@ "generator": "bazel" } } - ], - "generatedFiles": [ - ".flake8", - ".github/CONTRIBUTING.md", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/release-please.yml", - ".github/snippet-bot.yml", - ".gitignore", - ".kokoro/build.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/continuous.cfg", - ".kokoro/docker/docs/Dockerfile", - ".kokoro/docker/docs/fetch_gpg_keys.sh", - ".kokoro/docs/common.cfg", - ".kokoro/docs/docs-presubmit.cfg", - ".kokoro/docs/docs.cfg", - ".kokoro/populate-secrets.sh", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/publish-docs.sh", - ".kokoro/release.sh", - ".kokoro/release/common.cfg", - ".kokoro/release/release.cfg", - ".kokoro/samples/lint/common.cfg", - ".kokoro/samples/lint/continuous.cfg", - ".kokoro/samples/lint/periodic.cfg", - ".kokoro/samples/lint/presubmit.cfg", - ".kokoro/samples/python3.6/common.cfg", - ".kokoro/samples/python3.6/continuous.cfg", - ".kokoro/samples/python3.6/periodic.cfg", - ".kokoro/samples/python3.6/presubmit.cfg", - ".kokoro/samples/python3.7/common.cfg", - ".kokoro/samples/python3.7/continuous.cfg", - ".kokoro/samples/python3.7/periodic.cfg", - ".kokoro/samples/python3.7/presubmit.cfg", - ".kokoro/samples/python3.8/common.cfg", - ".kokoro/samples/python3.8/continuous.cfg", - ".kokoro/samples/python3.8/periodic.cfg", - ".kokoro/samples/python3.8/presubmit.cfg", - ".kokoro/test-samples.sh", - ".kokoro/trampoline.sh", - ".kokoro/trampoline_v2.sh", - ".trampolinerc", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.rst", - "LICENSE", - "MANIFEST.in", - "docs/_static/custom.css", - "docs/_templates/layout.html", - "docs/asset_v1/services.rst", - "docs/asset_v1/types.rst", - "docs/asset_v1beta1/services.rst", - "docs/asset_v1beta1/types.rst", - "docs/asset_v1p1beta1/services.rst", - "docs/asset_v1p1beta1/types.rst", - "docs/asset_v1p2beta1/services.rst", - "docs/asset_v1p2beta1/types.rst", - "docs/asset_v1p4beta1/services.rst", - "docs/asset_v1p4beta1/types.rst", - "docs/asset_v1p5beta1/services.rst", - "docs/asset_v1p5beta1/types.rst", - "docs/conf.py", - "docs/multiprocessing.rst", - "google/cloud/asset/__init__.py", - "google/cloud/asset/py.typed", - "google/cloud/asset_v1/__init__.py", - "google/cloud/asset_v1/py.typed", - "google/cloud/asset_v1/services/__init__.py", - "google/cloud/asset_v1/services/asset_service/__init__.py", - "google/cloud/asset_v1/services/asset_service/async_client.py", - "google/cloud/asset_v1/services/asset_service/client.py", - "google/cloud/asset_v1/services/asset_service/pagers.py", - "google/cloud/asset_v1/services/asset_service/transports/__init__.py", - "google/cloud/asset_v1/services/asset_service/transports/base.py", - "google/cloud/asset_v1/services/asset_service/transports/grpc.py", - "google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py", - "google/cloud/asset_v1/types/__init__.py", - "google/cloud/asset_v1/types/asset_service.py", - "google/cloud/asset_v1/types/assets.py", - "google/cloud/asset_v1beta1/__init__.py", - "google/cloud/asset_v1beta1/py.typed", - "google/cloud/asset_v1beta1/services/__init__.py", - "google/cloud/asset_v1beta1/services/asset_service/__init__.py", - "google/cloud/asset_v1beta1/services/asset_service/async_client.py", - "google/cloud/asset_v1beta1/services/asset_service/client.py", - "google/cloud/asset_v1beta1/services/asset_service/transports/__init__.py", - "google/cloud/asset_v1beta1/services/asset_service/transports/base.py", - "google/cloud/asset_v1beta1/services/asset_service/transports/grpc.py", - "google/cloud/asset_v1beta1/services/asset_service/transports/grpc_asyncio.py", - "google/cloud/asset_v1beta1/types/__init__.py", - "google/cloud/asset_v1beta1/types/asset_service.py", - "google/cloud/asset_v1beta1/types/assets.py", - "google/cloud/asset_v1p1beta1/__init__.py", - "google/cloud/asset_v1p1beta1/py.typed", - "google/cloud/asset_v1p1beta1/services/__init__.py", - "google/cloud/asset_v1p1beta1/services/asset_service/__init__.py", - "google/cloud/asset_v1p1beta1/services/asset_service/async_client.py", - "google/cloud/asset_v1p1beta1/services/asset_service/client.py", - "google/cloud/asset_v1p1beta1/services/asset_service/pagers.py", - "google/cloud/asset_v1p1beta1/services/asset_service/transports/__init__.py", - "google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py", - "google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py", - "google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py", - "google/cloud/asset_v1p1beta1/types/__init__.py", - "google/cloud/asset_v1p1beta1/types/asset_service.py", - "google/cloud/asset_v1p1beta1/types/assets.py", - "google/cloud/asset_v1p2beta1/__init__.py", - "google/cloud/asset_v1p2beta1/py.typed", - "google/cloud/asset_v1p2beta1/services/__init__.py", - "google/cloud/asset_v1p2beta1/services/asset_service/__init__.py", - "google/cloud/asset_v1p2beta1/services/asset_service/async_client.py", - "google/cloud/asset_v1p2beta1/services/asset_service/client.py", - "google/cloud/asset_v1p2beta1/services/asset_service/transports/__init__.py", - "google/cloud/asset_v1p2beta1/services/asset_service/transports/base.py", - "google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py", - "google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py", - "google/cloud/asset_v1p2beta1/types/__init__.py", - "google/cloud/asset_v1p2beta1/types/asset_service.py", - "google/cloud/asset_v1p2beta1/types/assets.py", - "google/cloud/asset_v1p4beta1/__init__.py", - "google/cloud/asset_v1p4beta1/py.typed", - "google/cloud/asset_v1p4beta1/services/__init__.py", - "google/cloud/asset_v1p4beta1/services/asset_service/__init__.py", - "google/cloud/asset_v1p4beta1/services/asset_service/async_client.py", - "google/cloud/asset_v1p4beta1/services/asset_service/client.py", - "google/cloud/asset_v1p4beta1/services/asset_service/transports/__init__.py", - "google/cloud/asset_v1p4beta1/services/asset_service/transports/base.py", - "google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py", - "google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py", - "google/cloud/asset_v1p4beta1/types/__init__.py", - "google/cloud/asset_v1p4beta1/types/asset_service.py", - "google/cloud/asset_v1p4beta1/types/assets.py", - "google/cloud/asset_v1p5beta1/__init__.py", - "google/cloud/asset_v1p5beta1/py.typed", - "google/cloud/asset_v1p5beta1/services/__init__.py", - "google/cloud/asset_v1p5beta1/services/asset_service/__init__.py", - "google/cloud/asset_v1p5beta1/services/asset_service/async_client.py", - "google/cloud/asset_v1p5beta1/services/asset_service/client.py", - "google/cloud/asset_v1p5beta1/services/asset_service/pagers.py", - "google/cloud/asset_v1p5beta1/services/asset_service/transports/__init__.py", - "google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py", - "google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py", - "google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py", - "google/cloud/asset_v1p5beta1/types/__init__.py", - "google/cloud/asset_v1p5beta1/types/asset_service.py", - "google/cloud/asset_v1p5beta1/types/assets.py", - "mypy.ini", - "noxfile.py", - "renovate.json", - "samples/AUTHORING_GUIDE.md", - "samples/CONTRIBUTING.md", - "samples/snippets/noxfile.py", - "scripts/decrypt-secrets.sh", - "scripts/fixup_asset_v1_keywords.py", - "scripts/fixup_asset_v1beta1_keywords.py", - "scripts/fixup_asset_v1p1beta1_keywords.py", - "scripts/fixup_asset_v1p2beta1_keywords.py", - "scripts/fixup_asset_v1p4beta1_keywords.py", - "scripts/fixup_asset_v1p5beta1_keywords.py", - "scripts/readme-gen/readme_gen.py", - "scripts/readme-gen/templates/README.tmpl.rst", - "scripts/readme-gen/templates/auth.tmpl.rst", - "scripts/readme-gen/templates/auth_api_key.tmpl.rst", - "scripts/readme-gen/templates/install_deps.tmpl.rst", - "scripts/readme-gen/templates/install_portaudio.tmpl.rst", - "setup.cfg", - "testing/.gitignore", - "tests/unit/gapic/asset_v1/__init__.py", - "tests/unit/gapic/asset_v1/test_asset_service.py", - "tests/unit/gapic/asset_v1beta1/__init__.py", - "tests/unit/gapic/asset_v1beta1/test_asset_service.py", - "tests/unit/gapic/asset_v1p1beta1/__init__.py", - "tests/unit/gapic/asset_v1p1beta1/test_asset_service.py", - "tests/unit/gapic/asset_v1p2beta1/__init__.py", - "tests/unit/gapic/asset_v1p2beta1/test_asset_service.py", - "tests/unit/gapic/asset_v1p4beta1/__init__.py", - "tests/unit/gapic/asset_v1p4beta1/test_asset_service.py", - "tests/unit/gapic/asset_v1p5beta1/__init__.py", - "tests/unit/gapic/asset_v1p5beta1/test_asset_service.py" ] } \ No newline at end of file diff --git a/synth.py b/synth.py index 573a946f..eef5a28e 100644 --- a/synth.py +++ b/synth.py @@ -14,6 +14,8 @@ """This script is used to synthesize generated parts of this library.""" +import re + import synthtool as s from synthtool import gcp from synthtool.languages import python @@ -36,6 +38,40 @@ s.move(library, excludes=excludes) +# Fix import of 'osconfig' type +s.replace( + "google/cloud/asset_v1/types/assets.py", + "from google\.cloud\.osconfig\.v1 import inventory_pb2 as inventory", + "from google.cloud.osconfig_v1 import Inventory" +) + +s.replace( + "google/cloud/asset_v1/types/assets.py", + "message=inventory\.Inventory,", + "message=Inventory," +) + +# Remove broken `parse_asset_path` method +# The resource pattern is '*' which breaks the regex match +s.replace( + "google/cloud/**/client.py", + """@staticmethod + def parse_asset_path.*?@staticmethod""", + """@staticmethod""", + flags=re.MULTILINE | re.DOTALL +) + +s.replace( + "google/cloud/**/async_client.py", + """parse_asset_path = staticmethod\(AssetServiceClient\.parse_asset_path\)""", + "" +) +s.replace( + "tests/unit/**/test_asset_service.py", + """def test_parse_asset_path.*?def""", + """def""", + flags=re.MULTILINE | re.DOTALL, +) # ---------------------------------------------------------------------------- # Add templated files # ---------------------------------------------------------------------------- @@ -52,13 +88,22 @@ python.py_samples(skip_readmes=True) -# TODO(busunkim): Use latest sphinx after microgenerator transition -s.replace("noxfile.py", '''["']sphinx["']''', '"sphinx<3.0.0"') +s.replace( + "noxfile.py", + "google\.cloud\.cloudasset", + "google/cloud", +) + +s.replace( + "noxfile.py", + '''["']--cov=google\.cloud["'],''', + "", +) s.replace( "noxfile.py", - "google.cloud.cloudasset", - "google.cloud.asset", + """"--cov=tests.unit",""", + """"--cov=tests/unit",""", ) # Temporarily disable warnings due to diff --git a/tests/unit/gapic/asset_v1/test_asset_service.py b/tests/unit/gapic/asset_v1/test_asset_service.py index 5a0c5759..ff391b24 100644 --- a/tests/unit/gapic/asset_v1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1/test_asset_service.py @@ -43,6 +43,7 @@ from google.cloud.asset_v1.types import assets from google.longrunning import operations_pb2 from google.oauth2 import service_account +from google.protobuf import duration_pb2 as duration # type: ignore from google.protobuf import field_mask_pb2 as field_mask # type: ignore from google.protobuf import timestamp_pb2 as timestamp # type: ignore from google.type import expr_pb2 as expr # type: ignore @@ -97,12 +98,12 @@ def test_asset_service_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_client_get_transport_class(): @@ -446,7 +447,7 @@ def test_export_assets( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_assets), "__call__") as call: + with mock.patch.object(type(client.transport.export_assets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -467,19 +468,19 @@ def test_export_assets_from_dict(): @pytest.mark.asyncio -async def test_export_assets_async(transport: str = "grpc_asyncio"): +async def test_export_assets_async( + transport: str = "grpc_asyncio", request_type=asset_service.ExportAssetsRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.ExportAssetsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_assets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_assets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -491,12 +492,17 @@ async def test_export_assets_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.ExportAssetsRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_export_assets_async_from_dict(): + await test_export_assets_async(request_type=dict) + + def test_export_assets_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -506,7 +512,7 @@ def test_export_assets_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_assets), "__call__") as call: + with mock.patch.object(type(client.transport.export_assets), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.export_assets(request) @@ -531,9 +537,7 @@ async def test_export_assets_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_assets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_assets), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -563,7 +567,7 @@ def test_batch_get_assets_history( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.batch_get_assets_history), "__call__" + type(client.transport.batch_get_assets_history), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.BatchGetAssetsHistoryResponse() @@ -577,6 +581,7 @@ def test_batch_get_assets_history( assert args[0] == asset_service.BatchGetAssetsHistoryRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.BatchGetAssetsHistoryResponse) @@ -585,18 +590,21 @@ def test_batch_get_assets_history_from_dict(): @pytest.mark.asyncio -async def test_batch_get_assets_history_async(transport: str = "grpc_asyncio"): +async def test_batch_get_assets_history_async( + transport: str = "grpc_asyncio", + request_type=asset_service.BatchGetAssetsHistoryRequest, +): client = AssetServiceAsyncClient( credentials=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 = asset_service.BatchGetAssetsHistoryRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.batch_get_assets_history), "__call__" + type(client.transport.batch_get_assets_history), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -609,12 +617,17 @@ async def test_batch_get_assets_history_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.BatchGetAssetsHistoryRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.BatchGetAssetsHistoryResponse) +@pytest.mark.asyncio +async def test_batch_get_assets_history_async_from_dict(): + await test_batch_get_assets_history_async(request_type=dict) + + def test_batch_get_assets_history_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -625,7 +638,7 @@ def test_batch_get_assets_history_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.batch_get_assets_history), "__call__" + type(client.transport.batch_get_assets_history), "__call__" ) as call: call.return_value = asset_service.BatchGetAssetsHistoryResponse() @@ -652,7 +665,7 @@ async def test_batch_get_assets_history_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.batch_get_assets_history), "__call__" + type(client.transport.batch_get_assets_history), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.BatchGetAssetsHistoryResponse() @@ -682,7 +695,7 @@ def test_create_feed( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_feed), "__call__") as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed( name="name_value", @@ -700,6 +713,7 @@ def test_create_feed( assert args[0] == asset_service.CreateFeedRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.Feed) assert response.name == "name_value" @@ -716,19 +730,19 @@ def test_create_feed_from_dict(): @pytest.mark.asyncio -async def test_create_feed_async(transport: str = "grpc_asyncio"): +async def test_create_feed_async( + transport: str = "grpc_asyncio", request_type=asset_service.CreateFeedRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.CreateFeedRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.Feed( @@ -745,7 +759,7 @@ async def test_create_feed_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.CreateFeedRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.Feed) @@ -759,6 +773,11 @@ async def test_create_feed_async(transport: str = "grpc_asyncio"): assert response.content_type == asset_service.ContentType.RESOURCE +@pytest.mark.asyncio +async def test_create_feed_async_from_dict(): + await test_create_feed_async(request_type=dict) + + def test_create_feed_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -768,7 +787,7 @@ def test_create_feed_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_feed), "__call__") as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: call.return_value = asset_service.Feed() client.create_feed(request) @@ -793,9 +812,7 @@ async def test_create_feed_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(asset_service.Feed()) await client.create_feed(request) @@ -814,7 +831,7 @@ def test_create_feed_flattened(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_feed), "__call__") as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -846,9 +863,7 @@ async def test_create_feed_flattened_async(): client = AssetServiceAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -887,7 +902,7 @@ def test_get_feed(transport: str = "grpc", request_type=asset_service.GetFeedReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_feed), "__call__") as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed( name="name_value", @@ -905,6 +920,7 @@ def test_get_feed(transport: str = "grpc", request_type=asset_service.GetFeedReq assert args[0] == asset_service.GetFeedRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.Feed) assert response.name == "name_value" @@ -921,19 +937,19 @@ def test_get_feed_from_dict(): @pytest.mark.asyncio -async def test_get_feed_async(transport: str = "grpc_asyncio"): +async def test_get_feed_async( + transport: str = "grpc_asyncio", request_type=asset_service.GetFeedRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.GetFeedRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.Feed( @@ -950,7 +966,7 @@ async def test_get_feed_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.GetFeedRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.Feed) @@ -964,6 +980,11 @@ async def test_get_feed_async(transport: str = "grpc_asyncio"): assert response.content_type == asset_service.ContentType.RESOURCE +@pytest.mark.asyncio +async def test_get_feed_async_from_dict(): + await test_get_feed_async(request_type=dict) + + def test_get_feed_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -973,7 +994,7 @@ def test_get_feed_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_feed), "__call__") as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: call.return_value = asset_service.Feed() client.get_feed(request) @@ -998,9 +1019,7 @@ async def test_get_feed_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(asset_service.Feed()) await client.get_feed(request) @@ -1019,7 +1038,7 @@ def test_get_feed_flattened(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_feed), "__call__") as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -1051,9 +1070,7 @@ async def test_get_feed_flattened_async(): client = AssetServiceAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -1094,7 +1111,7 @@ def test_list_feeds( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_feeds), "__call__") as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.ListFeedsResponse() @@ -1107,6 +1124,7 @@ def test_list_feeds( assert args[0] == asset_service.ListFeedsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.ListFeedsResponse) @@ -1115,19 +1133,19 @@ def test_list_feeds_from_dict(): @pytest.mark.asyncio -async def test_list_feeds_async(transport: str = "grpc_asyncio"): +async def test_list_feeds_async( + transport: str = "grpc_asyncio", request_type=asset_service.ListFeedsRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.ListFeedsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_feeds), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.ListFeedsResponse() @@ -1139,12 +1157,17 @@ async def test_list_feeds_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.ListFeedsRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.ListFeedsResponse) +@pytest.mark.asyncio +async def test_list_feeds_async_from_dict(): + await test_list_feeds_async(request_type=dict) + + def test_list_feeds_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -1154,7 +1177,7 @@ def test_list_feeds_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_feeds), "__call__") as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: call.return_value = asset_service.ListFeedsResponse() client.list_feeds(request) @@ -1179,9 +1202,7 @@ async def test_list_feeds_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_feeds), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.ListFeedsResponse() ) @@ -1202,7 +1223,7 @@ def test_list_feeds_flattened(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_feeds), "__call__") as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.ListFeedsResponse() @@ -1234,9 +1255,7 @@ async def test_list_feeds_flattened_async(): client = AssetServiceAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_feeds), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.ListFeedsResponse() @@ -1279,7 +1298,7 @@ def test_update_feed( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_feed), "__call__") as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed( name="name_value", @@ -1297,6 +1316,7 @@ def test_update_feed( assert args[0] == asset_service.UpdateFeedRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.Feed) assert response.name == "name_value" @@ -1313,19 +1333,19 @@ def test_update_feed_from_dict(): @pytest.mark.asyncio -async def test_update_feed_async(transport: str = "grpc_asyncio"): +async def test_update_feed_async( + transport: str = "grpc_asyncio", request_type=asset_service.UpdateFeedRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.UpdateFeedRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.Feed( @@ -1342,7 +1362,7 @@ async def test_update_feed_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.UpdateFeedRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.Feed) @@ -1356,6 +1376,11 @@ async def test_update_feed_async(transport: str = "grpc_asyncio"): assert response.content_type == asset_service.ContentType.RESOURCE +@pytest.mark.asyncio +async def test_update_feed_async_from_dict(): + await test_update_feed_async(request_type=dict) + + def test_update_feed_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -1365,7 +1390,7 @@ def test_update_feed_field_headers(): request.feed.name = "feed.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_feed), "__call__") as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: call.return_value = asset_service.Feed() client.update_feed(request) @@ -1390,9 +1415,7 @@ async def test_update_feed_field_headers_async(): request.feed.name = "feed.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(asset_service.Feed()) await client.update_feed(request) @@ -1411,7 +1434,7 @@ def test_update_feed_flattened(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_feed), "__call__") as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -1444,9 +1467,7 @@ async def test_update_feed_flattened_async(): client = AssetServiceAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -1488,7 +1509,7 @@ def test_delete_feed( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_feed), "__call__") as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = None @@ -1509,19 +1530,19 @@ def test_delete_feed_from_dict(): @pytest.mark.asyncio -async def test_delete_feed_async(transport: str = "grpc_asyncio"): +async def test_delete_feed_async( + transport: str = "grpc_asyncio", request_type=asset_service.DeleteFeedRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.DeleteFeedRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) @@ -1531,12 +1552,17 @@ async def test_delete_feed_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.DeleteFeedRequest() # Establish that the response is the type that we expect. assert response is None +@pytest.mark.asyncio +async def test_delete_feed_async_from_dict(): + await test_delete_feed_async(request_type=dict) + + def test_delete_feed_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -1546,7 +1572,7 @@ def test_delete_feed_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_feed), "__call__") as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: call.return_value = None client.delete_feed(request) @@ -1571,9 +1597,7 @@ async def test_delete_feed_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) await client.delete_feed(request) @@ -1592,7 +1616,7 @@ def test_delete_feed_flattened(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_feed), "__call__") as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = None @@ -1624,9 +1648,7 @@ async def test_delete_feed_flattened_async(): client = AssetServiceAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = None @@ -1668,7 +1690,7 @@ def test_search_all_resources( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllResourcesResponse( @@ -1684,6 +1706,7 @@ def test_search_all_resources( assert args[0] == asset_service.SearchAllResourcesRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchAllResourcesPager) assert response.next_page_token == "next_page_token_value" @@ -1694,18 +1717,21 @@ def test_search_all_resources_from_dict(): @pytest.mark.asyncio -async def test_search_all_resources_async(transport: str = "grpc_asyncio"): +async def test_search_all_resources_async( + transport: str = "grpc_asyncio", + request_type=asset_service.SearchAllResourcesRequest, +): client = AssetServiceAsyncClient( credentials=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 = asset_service.SearchAllResourcesRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -1720,7 +1746,7 @@ async def test_search_all_resources_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.SearchAllResourcesRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.SearchAllResourcesAsyncPager) @@ -1728,6 +1754,11 @@ async def test_search_all_resources_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_search_all_resources_async_from_dict(): + await test_search_all_resources_async(request_type=dict) + + def test_search_all_resources_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -1738,7 +1769,7 @@ def test_search_all_resources_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: call.return_value = asset_service.SearchAllResourcesResponse() @@ -1765,7 +1796,7 @@ async def test_search_all_resources_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.SearchAllResourcesResponse() @@ -1788,7 +1819,7 @@ def test_search_all_resources_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllResourcesResponse() @@ -1831,7 +1862,7 @@ async def test_search_all_resources_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllResourcesResponse() @@ -1877,7 +1908,7 @@ def test_search_all_resources_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1919,7 +1950,7 @@ def test_search_all_resources_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1953,7 +1984,7 @@ async def test_search_all_resources_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_resources), + type(client.transport.search_all_resources), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -1994,7 +2025,7 @@ async def test_search_all_resources_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_resources), + type(client.transport.search_all_resources), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -2039,7 +2070,7 @@ def test_search_all_iam_policies( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllIamPoliciesResponse( @@ -2055,6 +2086,7 @@ def test_search_all_iam_policies( assert args[0] == asset_service.SearchAllIamPoliciesRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchAllIamPoliciesPager) assert response.next_page_token == "next_page_token_value" @@ -2065,18 +2097,21 @@ def test_search_all_iam_policies_from_dict(): @pytest.mark.asyncio -async def test_search_all_iam_policies_async(transport: str = "grpc_asyncio"): +async def test_search_all_iam_policies_async( + transport: str = "grpc_asyncio", + request_type=asset_service.SearchAllIamPoliciesRequest, +): client = AssetServiceAsyncClient( credentials=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 = asset_service.SearchAllIamPoliciesRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -2091,7 +2126,7 @@ async def test_search_all_iam_policies_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.SearchAllIamPoliciesRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.SearchAllIamPoliciesAsyncPager) @@ -2099,6 +2134,11 @@ async def test_search_all_iam_policies_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_search_all_iam_policies_async_from_dict(): + await test_search_all_iam_policies_async(request_type=dict) + + def test_search_all_iam_policies_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -2109,7 +2149,7 @@ def test_search_all_iam_policies_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: call.return_value = asset_service.SearchAllIamPoliciesResponse() @@ -2136,7 +2176,7 @@ async def test_search_all_iam_policies_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.SearchAllIamPoliciesResponse() @@ -2159,7 +2199,7 @@ def test_search_all_iam_policies_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllIamPoliciesResponse() @@ -2199,7 +2239,7 @@ async def test_search_all_iam_policies_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllIamPoliciesResponse() @@ -2242,7 +2282,7 @@ def test_search_all_iam_policies_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -2287,7 +2327,7 @@ def test_search_all_iam_policies_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -2324,7 +2364,7 @@ async def test_search_all_iam_policies_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_iam_policies), + type(client.transport.search_all_iam_policies), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -2368,7 +2408,7 @@ async def test_search_all_iam_policies_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_iam_policies), + type(client.transport.search_all_iam_policies), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -2403,6 +2443,279 @@ async def test_search_all_iam_policies_async_pages(): assert page_.raw_page.next_page_token == token +def test_analyze_iam_policy( + transport: str = "grpc", request_type=asset_service.AnalyzeIamPolicyRequest +): + client = AssetServiceClient( + credentials=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.analyze_iam_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = asset_service.AnalyzeIamPolicyResponse(fully_explored=True,) + + response = client.analyze_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] == asset_service.AnalyzeIamPolicyRequest() + + # Establish that the response is the type that we expect. + + assert isinstance(response, asset_service.AnalyzeIamPolicyResponse) + + assert response.fully_explored is True + + +def test_analyze_iam_policy_from_dict(): + test_analyze_iam_policy(request_type=dict) + + +@pytest.mark.asyncio +async def test_analyze_iam_policy_async( + transport: str = "grpc_asyncio", request_type=asset_service.AnalyzeIamPolicyRequest +): + client = AssetServiceAsyncClient( + credentials=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.analyze_iam_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + asset_service.AnalyzeIamPolicyResponse(fully_explored=True,) + ) + + response = await client.analyze_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] == asset_service.AnalyzeIamPolicyRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.AnalyzeIamPolicyResponse) + + assert response.fully_explored is True + + +@pytest.mark.asyncio +async def test_analyze_iam_policy_async_from_dict(): + await test_analyze_iam_policy_async(request_type=dict) + + +def test_analyze_iam_policy_field_headers(): + client = AssetServiceClient(credentials=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 = asset_service.AnalyzeIamPolicyRequest() + request.analysis_query.scope = "analysis_query.scope/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.analyze_iam_policy), "__call__" + ) as call: + call.return_value = asset_service.AnalyzeIamPolicyResponse() + + client.analyze_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", + "analysis_query.scope=analysis_query.scope/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_analyze_iam_policy_field_headers_async(): + client = AssetServiceAsyncClient(credentials=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 = asset_service.AnalyzeIamPolicyRequest() + request.analysis_query.scope = "analysis_query.scope/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.analyze_iam_policy), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + asset_service.AnalyzeIamPolicyResponse() + ) + + await client.analyze_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", + "analysis_query.scope=analysis_query.scope/value", + ) in kw["metadata"] + + +def test_analyze_iam_policy_longrunning( + transport: str = "grpc", + request_type=asset_service.AnalyzeIamPolicyLongrunningRequest, +): + client = AssetServiceClient( + credentials=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.analyze_iam_policy_longrunning), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + + response = client.analyze_iam_policy_longrunning(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == asset_service.AnalyzeIamPolicyLongrunningRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_analyze_iam_policy_longrunning_from_dict(): + test_analyze_iam_policy_longrunning(request_type=dict) + + +@pytest.mark.asyncio +async def test_analyze_iam_policy_longrunning_async( + transport: str = "grpc_asyncio", + request_type=asset_service.AnalyzeIamPolicyLongrunningRequest, +): + client = AssetServiceAsyncClient( + credentials=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.analyze_iam_policy_longrunning), "__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.analyze_iam_policy_longrunning(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == asset_service.AnalyzeIamPolicyLongrunningRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_analyze_iam_policy_longrunning_async_from_dict(): + await test_analyze_iam_policy_longrunning_async(request_type=dict) + + +def test_analyze_iam_policy_longrunning_field_headers(): + client = AssetServiceClient(credentials=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 = asset_service.AnalyzeIamPolicyLongrunningRequest() + request.analysis_query.scope = "analysis_query.scope/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.analyze_iam_policy_longrunning), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + + client.analyze_iam_policy_longrunning(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", + "analysis_query.scope=analysis_query.scope/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_analyze_iam_policy_longrunning_field_headers_async(): + client = AssetServiceAsyncClient(credentials=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 = asset_service.AnalyzeIamPolicyLongrunningRequest() + request.analysis_query.scope = "analysis_query.scope/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.analyze_iam_policy_longrunning), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + + await client.analyze_iam_policy_longrunning(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", + "analysis_query.scope=analysis_query.scope/value", + ) in kw["metadata"] + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.AssetServiceGrpcTransport( @@ -2439,7 +2752,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = AssetServiceClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -2472,7 +2785,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.AssetServiceGrpcTransport,) + assert isinstance(client.transport, transports.AssetServiceGrpcTransport,) def test_asset_service_base_transport_error(): @@ -2506,6 +2819,8 @@ def test_asset_service_base_transport(): "delete_feed", "search_all_resources", "search_all_iam_policies", + "analyze_iam_policy", + "analyze_iam_policy_longrunning", ) for method in methods: with pytest.raises(NotImplementedError): @@ -2579,7 +2894,7 @@ def test_asset_service_host_no_port(): api_endpoint="cloudasset.googleapis.com" ), ) - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_host_with_port(): @@ -2589,7 +2904,7 @@ def test_asset_service_host_with_port(): api_endpoint="cloudasset.googleapis.com:8000" ), ) - assert client._transport._host == "cloudasset.googleapis.com:8000" + assert client.transport._host == "cloudasset.googleapis.com:8000" def test_asset_service_grpc_transport_channel(): @@ -2601,6 +2916,7 @@ def test_asset_service_grpc_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None def test_asset_service_grpc_asyncio_transport_channel(): @@ -2612,6 +2928,7 @@ def test_asset_service_grpc_asyncio_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None @pytest.mark.parametrize( @@ -2654,6 +2971,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_ quota_project_id=None, ) assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred @pytest.mark.parametrize( @@ -2697,7 +3015,7 @@ def test_asset_service_grpc_lro_client(): client = AssetServiceClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -2710,7 +3028,7 @@ def test_asset_service_grpc_lro_async_client(): client = AssetServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client._client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -2719,6 +3037,13 @@ def test_asset_service_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client +def test_asset_path(): + + expected = "*".format() + actual = AssetServiceClient.asset_path() + assert expected == actual + + def test_feed_path(): project = "squid" feed = "clam" @@ -2740,6 +3065,107 @@ def test_parse_feed_path(): assert expected == actual +def test_common_billing_account_path(): + billing_account = "oyster" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AssetServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = AssetServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "cuttlefish" + + expected = "folders/{folder}".format(folder=folder,) + actual = AssetServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = AssetServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "winkle" + + expected = "organizations/{organization}".format(organization=organization,) + actual = AssetServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = AssetServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "scallop" + + expected = "projects/{project}".format(project=project,) + actual = AssetServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = AssetServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.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 = AssetServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = AssetServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/asset_v1beta1/test_asset_service.py b/tests/unit/gapic/asset_v1beta1/test_asset_service.py index c689396e..83bf52f0 100644 --- a/tests/unit/gapic/asset_v1beta1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1beta1/test_asset_service.py @@ -94,12 +94,12 @@ def test_asset_service_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_client_get_transport_class(): @@ -443,7 +443,7 @@ def test_export_assets( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_assets), "__call__") as call: + with mock.patch.object(type(client.transport.export_assets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -464,19 +464,19 @@ def test_export_assets_from_dict(): @pytest.mark.asyncio -async def test_export_assets_async(transport: str = "grpc_asyncio"): +async def test_export_assets_async( + transport: str = "grpc_asyncio", request_type=asset_service.ExportAssetsRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.ExportAssetsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_assets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_assets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") @@ -488,12 +488,17 @@ async def test_export_assets_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.ExportAssetsRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_export_assets_async_from_dict(): + await test_export_assets_async(request_type=dict) + + def test_export_assets_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -503,7 +508,7 @@ def test_export_assets_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.export_assets), "__call__") as call: + with mock.patch.object(type(client.transport.export_assets), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") client.export_assets(request) @@ -528,9 +533,7 @@ async def test_export_assets_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.export_assets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.export_assets), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) @@ -560,7 +563,7 @@ def test_batch_get_assets_history( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.batch_get_assets_history), "__call__" + type(client.transport.batch_get_assets_history), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.BatchGetAssetsHistoryResponse() @@ -574,6 +577,7 @@ def test_batch_get_assets_history( assert args[0] == asset_service.BatchGetAssetsHistoryRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.BatchGetAssetsHistoryResponse) @@ -582,18 +586,21 @@ def test_batch_get_assets_history_from_dict(): @pytest.mark.asyncio -async def test_batch_get_assets_history_async(transport: str = "grpc_asyncio"): +async def test_batch_get_assets_history_async( + transport: str = "grpc_asyncio", + request_type=asset_service.BatchGetAssetsHistoryRequest, +): client = AssetServiceAsyncClient( credentials=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 = asset_service.BatchGetAssetsHistoryRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.batch_get_assets_history), "__call__" + type(client.transport.batch_get_assets_history), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -606,12 +613,17 @@ async def test_batch_get_assets_history_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.BatchGetAssetsHistoryRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.BatchGetAssetsHistoryResponse) +@pytest.mark.asyncio +async def test_batch_get_assets_history_async_from_dict(): + await test_batch_get_assets_history_async(request_type=dict) + + def test_batch_get_assets_history_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -622,7 +634,7 @@ def test_batch_get_assets_history_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.batch_get_assets_history), "__call__" + type(client.transport.batch_get_assets_history), "__call__" ) as call: call.return_value = asset_service.BatchGetAssetsHistoryResponse() @@ -649,7 +661,7 @@ async def test_batch_get_assets_history_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.batch_get_assets_history), "__call__" + type(client.transport.batch_get_assets_history), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.BatchGetAssetsHistoryResponse() @@ -703,7 +715,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = AssetServiceClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -736,7 +748,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.AssetServiceGrpcTransport,) + assert isinstance(client.transport, transports.AssetServiceGrpcTransport,) def test_asset_service_base_transport_error(): @@ -836,7 +848,7 @@ def test_asset_service_host_no_port(): api_endpoint="cloudasset.googleapis.com" ), ) - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_host_with_port(): @@ -846,7 +858,7 @@ def test_asset_service_host_with_port(): api_endpoint="cloudasset.googleapis.com:8000" ), ) - assert client._transport._host == "cloudasset.googleapis.com:8000" + assert client.transport._host == "cloudasset.googleapis.com:8000" def test_asset_service_grpc_transport_channel(): @@ -858,6 +870,7 @@ def test_asset_service_grpc_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None def test_asset_service_grpc_asyncio_transport_channel(): @@ -869,6 +882,7 @@ def test_asset_service_grpc_asyncio_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None @pytest.mark.parametrize( @@ -911,6 +925,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_ quota_project_id=None, ) assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred @pytest.mark.parametrize( @@ -954,7 +969,7 @@ def test_asset_service_grpc_lro_client(): client = AssetServiceClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -967,7 +982,7 @@ def test_asset_service_grpc_lro_async_client(): client = AssetServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client._client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -976,6 +991,114 @@ def test_asset_service_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client +def test_asset_path(): + + expected = "*".format() + actual = AssetServiceClient.asset_path() + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "squid" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AssetServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = AssetServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + + expected = "folders/{folder}".format(folder=folder,) + actual = AssetServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = AssetServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + + expected = "organizations/{organization}".format(organization=organization,) + actual = AssetServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = AssetServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + + expected = "projects/{project}".format(project=project,) + actual = AssetServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = AssetServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = AssetServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = AssetServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py index 18c73580..b1bcae16 100644 --- a/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py @@ -90,12 +90,12 @@ def test_asset_service_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_client_get_transport_class(): @@ -440,7 +440,7 @@ def test_search_all_resources( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllResourcesResponse( @@ -456,6 +456,7 @@ def test_search_all_resources( assert args[0] == asset_service.SearchAllResourcesRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchAllResourcesPager) assert response.next_page_token == "next_page_token_value" @@ -466,18 +467,21 @@ def test_search_all_resources_from_dict(): @pytest.mark.asyncio -async def test_search_all_resources_async(transport: str = "grpc_asyncio"): +async def test_search_all_resources_async( + transport: str = "grpc_asyncio", + request_type=asset_service.SearchAllResourcesRequest, +): client = AssetServiceAsyncClient( credentials=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 = asset_service.SearchAllResourcesRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -492,7 +496,7 @@ async def test_search_all_resources_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.SearchAllResourcesRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.SearchAllResourcesAsyncPager) @@ -500,6 +504,11 @@ async def test_search_all_resources_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_search_all_resources_async_from_dict(): + await test_search_all_resources_async(request_type=dict) + + def test_search_all_resources_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -510,7 +519,7 @@ def test_search_all_resources_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: call.return_value = asset_service.SearchAllResourcesResponse() @@ -537,7 +546,7 @@ async def test_search_all_resources_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.SearchAllResourcesResponse() @@ -560,7 +569,7 @@ def test_search_all_resources_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllResourcesResponse() @@ -603,7 +612,7 @@ async def test_search_all_resources_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllResourcesResponse() @@ -649,7 +658,7 @@ def test_search_all_resources_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -694,7 +703,7 @@ def test_search_all_resources_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_resources), "__call__" + type(client.transport.search_all_resources), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -731,7 +740,7 @@ async def test_search_all_resources_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_resources), + type(client.transport.search_all_resources), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -775,7 +784,7 @@ async def test_search_all_resources_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_resources), + type(client.transport.search_all_resources), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -823,7 +832,7 @@ def test_search_all_iam_policies( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllIamPoliciesResponse( @@ -839,6 +848,7 @@ def test_search_all_iam_policies( assert args[0] == asset_service.SearchAllIamPoliciesRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchAllIamPoliciesPager) assert response.next_page_token == "next_page_token_value" @@ -849,18 +859,21 @@ def test_search_all_iam_policies_from_dict(): @pytest.mark.asyncio -async def test_search_all_iam_policies_async(transport: str = "grpc_asyncio"): +async def test_search_all_iam_policies_async( + transport: str = "grpc_asyncio", + request_type=asset_service.SearchAllIamPoliciesRequest, +): client = AssetServiceAsyncClient( credentials=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 = asset_service.SearchAllIamPoliciesRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -875,7 +888,7 @@ async def test_search_all_iam_policies_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.SearchAllIamPoliciesRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.SearchAllIamPoliciesAsyncPager) @@ -883,6 +896,11 @@ async def test_search_all_iam_policies_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_search_all_iam_policies_async_from_dict(): + await test_search_all_iam_policies_async(request_type=dict) + + def test_search_all_iam_policies_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -893,7 +911,7 @@ def test_search_all_iam_policies_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: call.return_value = asset_service.SearchAllIamPoliciesResponse() @@ -920,7 +938,7 @@ async def test_search_all_iam_policies_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.SearchAllIamPoliciesResponse() @@ -943,7 +961,7 @@ def test_search_all_iam_policies_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllIamPoliciesResponse() @@ -983,7 +1001,7 @@ async def test_search_all_iam_policies_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.SearchAllIamPoliciesResponse() @@ -1026,7 +1044,7 @@ def test_search_all_iam_policies_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1071,7 +1089,7 @@ def test_search_all_iam_policies_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.search_all_iam_policies), "__call__" + type(client.transport.search_all_iam_policies), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -1108,7 +1126,7 @@ async def test_search_all_iam_policies_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_iam_policies), + type(client.transport.search_all_iam_policies), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -1152,7 +1170,7 @@ async def test_search_all_iam_policies_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.search_all_iam_policies), + type(client.transport.search_all_iam_policies), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -1223,7 +1241,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = AssetServiceClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -1256,7 +1274,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.AssetServiceGrpcTransport,) + assert isinstance(client.transport, transports.AssetServiceGrpcTransport,) def test_asset_service_base_transport_error(): @@ -1351,7 +1369,7 @@ def test_asset_service_host_no_port(): api_endpoint="cloudasset.googleapis.com" ), ) - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_host_with_port(): @@ -1361,7 +1379,7 @@ def test_asset_service_host_with_port(): api_endpoint="cloudasset.googleapis.com:8000" ), ) - assert client._transport._host == "cloudasset.googleapis.com:8000" + assert client.transport._host == "cloudasset.googleapis.com:8000" def test_asset_service_grpc_transport_channel(): @@ -1373,6 +1391,7 @@ def test_asset_service_grpc_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None def test_asset_service_grpc_asyncio_transport_channel(): @@ -1384,6 +1403,7 @@ def test_asset_service_grpc_asyncio_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None @pytest.mark.parametrize( @@ -1426,6 +1446,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_ quota_project_id=None, ) assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred @pytest.mark.parametrize( @@ -1465,6 +1486,107 @@ def test_asset_service_transport_channel_mtls_with_adc(transport_class): assert transport.grpc_channel == mock_grpc_channel +def test_common_billing_account_path(): + billing_account = "squid" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AssetServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = AssetServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + + expected = "folders/{folder}".format(folder=folder,) + actual = AssetServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = AssetServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + + expected = "organizations/{organization}".format(organization=organization,) + actual = AssetServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = AssetServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + + expected = "projects/{project}".format(project=project,) + actual = AssetServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = AssetServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = AssetServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = AssetServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py index c7f048a7..b355f0ab 100644 --- a/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py @@ -89,12 +89,12 @@ def test_asset_service_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_client_get_transport_class(): @@ -438,7 +438,7 @@ def test_create_feed( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_feed), "__call__") as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed( name="name_value", @@ -456,6 +456,7 @@ def test_create_feed( assert args[0] == asset_service.CreateFeedRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.Feed) assert response.name == "name_value" @@ -472,19 +473,19 @@ def test_create_feed_from_dict(): @pytest.mark.asyncio -async def test_create_feed_async(transport: str = "grpc_asyncio"): +async def test_create_feed_async( + transport: str = "grpc_asyncio", request_type=asset_service.CreateFeedRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.CreateFeedRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.Feed( @@ -501,7 +502,7 @@ async def test_create_feed_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.CreateFeedRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.Feed) @@ -515,6 +516,11 @@ async def test_create_feed_async(transport: str = "grpc_asyncio"): assert response.content_type == asset_service.ContentType.RESOURCE +@pytest.mark.asyncio +async def test_create_feed_async_from_dict(): + await test_create_feed_async(request_type=dict) + + def test_create_feed_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -524,7 +530,7 @@ def test_create_feed_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_feed), "__call__") as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: call.return_value = asset_service.Feed() client.create_feed(request) @@ -549,9 +555,7 @@ async def test_create_feed_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(asset_service.Feed()) await client.create_feed(request) @@ -570,7 +574,7 @@ def test_create_feed_flattened(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_feed), "__call__") as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -602,9 +606,7 @@ async def test_create_feed_flattened_async(): client = AssetServiceAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.create_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -643,7 +645,7 @@ def test_get_feed(transport: str = "grpc", request_type=asset_service.GetFeedReq request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_feed), "__call__") as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed( name="name_value", @@ -661,6 +663,7 @@ def test_get_feed(transport: str = "grpc", request_type=asset_service.GetFeedReq assert args[0] == asset_service.GetFeedRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.Feed) assert response.name == "name_value" @@ -677,19 +680,19 @@ def test_get_feed_from_dict(): @pytest.mark.asyncio -async def test_get_feed_async(transport: str = "grpc_asyncio"): +async def test_get_feed_async( + transport: str = "grpc_asyncio", request_type=asset_service.GetFeedRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.GetFeedRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.Feed( @@ -706,7 +709,7 @@ async def test_get_feed_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.GetFeedRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.Feed) @@ -720,6 +723,11 @@ async def test_get_feed_async(transport: str = "grpc_asyncio"): assert response.content_type == asset_service.ContentType.RESOURCE +@pytest.mark.asyncio +async def test_get_feed_async_from_dict(): + await test_get_feed_async(request_type=dict) + + def test_get_feed_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -729,7 +737,7 @@ def test_get_feed_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_feed), "__call__") as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: call.return_value = asset_service.Feed() client.get_feed(request) @@ -754,9 +762,7 @@ async def test_get_feed_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(asset_service.Feed()) await client.get_feed(request) @@ -775,7 +781,7 @@ def test_get_feed_flattened(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_feed), "__call__") as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -807,9 +813,7 @@ async def test_get_feed_flattened_async(): client = AssetServiceAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.get_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -850,7 +854,7 @@ def test_list_feeds( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_feeds), "__call__") as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.ListFeedsResponse() @@ -863,6 +867,7 @@ def test_list_feeds( assert args[0] == asset_service.ListFeedsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.ListFeedsResponse) @@ -871,19 +876,19 @@ def test_list_feeds_from_dict(): @pytest.mark.asyncio -async def test_list_feeds_async(transport: str = "grpc_asyncio"): +async def test_list_feeds_async( + transport: str = "grpc_asyncio", request_type=asset_service.ListFeedsRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.ListFeedsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_feeds), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.ListFeedsResponse() @@ -895,12 +900,17 @@ async def test_list_feeds_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.ListFeedsRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.ListFeedsResponse) +@pytest.mark.asyncio +async def test_list_feeds_async_from_dict(): + await test_list_feeds_async(request_type=dict) + + def test_list_feeds_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -910,7 +920,7 @@ def test_list_feeds_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_feeds), "__call__") as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: call.return_value = asset_service.ListFeedsResponse() client.list_feeds(request) @@ -935,9 +945,7 @@ async def test_list_feeds_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_feeds), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.ListFeedsResponse() ) @@ -958,7 +966,7 @@ def test_list_feeds_flattened(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_feeds), "__call__") as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.ListFeedsResponse() @@ -990,9 +998,7 @@ async def test_list_feeds_flattened_async(): client = AssetServiceAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_feeds), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_feeds), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.ListFeedsResponse() @@ -1035,7 +1041,7 @@ def test_update_feed( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_feed), "__call__") as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed( name="name_value", @@ -1053,6 +1059,7 @@ def test_update_feed( assert args[0] == asset_service.UpdateFeedRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.Feed) assert response.name == "name_value" @@ -1069,19 +1076,19 @@ def test_update_feed_from_dict(): @pytest.mark.asyncio -async def test_update_feed_async(transport: str = "grpc_asyncio"): +async def test_update_feed_async( + transport: str = "grpc_asyncio", request_type=asset_service.UpdateFeedRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.UpdateFeedRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.Feed( @@ -1098,7 +1105,7 @@ async def test_update_feed_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.UpdateFeedRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.Feed) @@ -1112,6 +1119,11 @@ async def test_update_feed_async(transport: str = "grpc_asyncio"): assert response.content_type == asset_service.ContentType.RESOURCE +@pytest.mark.asyncio +async def test_update_feed_async_from_dict(): + await test_update_feed_async(request_type=dict) + + def test_update_feed_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -1121,7 +1133,7 @@ def test_update_feed_field_headers(): request.feed.name = "feed.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_feed), "__call__") as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: call.return_value = asset_service.Feed() client.update_feed(request) @@ -1146,9 +1158,7 @@ async def test_update_feed_field_headers_async(): request.feed.name = "feed.name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(asset_service.Feed()) await client.update_feed(request) @@ -1167,7 +1177,7 @@ def test_update_feed_flattened(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_feed), "__call__") as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -1200,9 +1210,7 @@ async def test_update_feed_flattened_async(): client = AssetServiceAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.update_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.Feed() @@ -1244,7 +1252,7 @@ def test_delete_feed( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_feed), "__call__") as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = None @@ -1265,19 +1273,19 @@ def test_delete_feed_from_dict(): @pytest.mark.asyncio -async def test_delete_feed_async(transport: str = "grpc_asyncio"): +async def test_delete_feed_async( + transport: str = "grpc_asyncio", request_type=asset_service.DeleteFeedRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.DeleteFeedRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) @@ -1287,12 +1295,17 @@ async def test_delete_feed_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.DeleteFeedRequest() # Establish that the response is the type that we expect. assert response is None +@pytest.mark.asyncio +async def test_delete_feed_async_from_dict(): + await test_delete_feed_async(request_type=dict) + + def test_delete_feed_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -1302,7 +1315,7 @@ def test_delete_feed_field_headers(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_feed), "__call__") as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: call.return_value = None client.delete_feed(request) @@ -1327,9 +1340,7 @@ async def test_delete_feed_field_headers_async(): request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) await client.delete_feed(request) @@ -1348,7 +1359,7 @@ def test_delete_feed_flattened(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_feed), "__call__") as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = None @@ -1380,9 +1391,7 @@ async def test_delete_feed_flattened_async(): client = AssetServiceAsyncClient(credentials=credentials.AnonymousCredentials(),) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_feed), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_feed), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = None @@ -1447,7 +1456,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = AssetServiceClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -1480,7 +1489,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.AssetServiceGrpcTransport,) + assert isinstance(client.transport, transports.AssetServiceGrpcTransport,) def test_asset_service_base_transport_error(): @@ -1578,7 +1587,7 @@ def test_asset_service_host_no_port(): api_endpoint="cloudasset.googleapis.com" ), ) - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_host_with_port(): @@ -1588,7 +1597,7 @@ def test_asset_service_host_with_port(): api_endpoint="cloudasset.googleapis.com:8000" ), ) - assert client._transport._host == "cloudasset.googleapis.com:8000" + assert client.transport._host == "cloudasset.googleapis.com:8000" def test_asset_service_grpc_transport_channel(): @@ -1600,6 +1609,7 @@ def test_asset_service_grpc_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None def test_asset_service_grpc_asyncio_transport_channel(): @@ -1611,6 +1621,7 @@ def test_asset_service_grpc_asyncio_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None @pytest.mark.parametrize( @@ -1653,6 +1664,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_ quota_project_id=None, ) assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred @pytest.mark.parametrize( @@ -1713,6 +1725,107 @@ def test_parse_feed_path(): assert expected == actual +def test_common_billing_account_path(): + billing_account = "oyster" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AssetServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = AssetServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "cuttlefish" + + expected = "folders/{folder}".format(folder=folder,) + actual = AssetServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = AssetServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "winkle" + + expected = "organizations/{organization}".format(organization=organization,) + actual = AssetServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = AssetServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "scallop" + + expected = "projects/{project}".format(project=project,) + actual = AssetServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = AssetServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.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 = AssetServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = AssetServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py index deae00b0..a555f8ce 100644 --- a/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py @@ -94,12 +94,12 @@ def test_asset_service_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_client_get_transport_class(): @@ -444,7 +444,7 @@ def test_analyze_iam_policy( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.analyze_iam_policy), "__call__" + type(client.transport.analyze_iam_policy), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = asset_service.AnalyzeIamPolicyResponse(fully_explored=True,) @@ -458,6 +458,7 @@ def test_analyze_iam_policy( assert args[0] == asset_service.AnalyzeIamPolicyRequest() # Establish that the response is the type that we expect. + assert isinstance(response, asset_service.AnalyzeIamPolicyResponse) assert response.fully_explored is True @@ -468,18 +469,20 @@ def test_analyze_iam_policy_from_dict(): @pytest.mark.asyncio -async def test_analyze_iam_policy_async(transport: str = "grpc_asyncio"): +async def test_analyze_iam_policy_async( + transport: str = "grpc_asyncio", request_type=asset_service.AnalyzeIamPolicyRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.AnalyzeIamPolicyRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.analyze_iam_policy), "__call__" + type(client.transport.analyze_iam_policy), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -492,7 +495,7 @@ async def test_analyze_iam_policy_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.AnalyzeIamPolicyRequest() # Establish that the response is the type that we expect. assert isinstance(response, asset_service.AnalyzeIamPolicyResponse) @@ -500,6 +503,11 @@ async def test_analyze_iam_policy_async(transport: str = "grpc_asyncio"): assert response.fully_explored is True +@pytest.mark.asyncio +async def test_analyze_iam_policy_async_from_dict(): + await test_analyze_iam_policy_async(request_type=dict) + + def test_analyze_iam_policy_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -510,7 +518,7 @@ def test_analyze_iam_policy_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.analyze_iam_policy), "__call__" + type(client.transport.analyze_iam_policy), "__call__" ) as call: call.return_value = asset_service.AnalyzeIamPolicyResponse() @@ -540,7 +548,7 @@ async def test_analyze_iam_policy_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.analyze_iam_policy), "__call__" + type(client.transport.analyze_iam_policy), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.AnalyzeIamPolicyResponse() @@ -574,7 +582,7 @@ def test_export_iam_policy_analysis( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.export_iam_policy_analysis), "__call__" + type(client.transport.export_iam_policy_analysis), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") @@ -596,18 +604,21 @@ def test_export_iam_policy_analysis_from_dict(): @pytest.mark.asyncio -async def test_export_iam_policy_analysis_async(transport: str = "grpc_asyncio"): +async def test_export_iam_policy_analysis_async( + transport: str = "grpc_asyncio", + request_type=asset_service.ExportIamPolicyAnalysisRequest, +): client = AssetServiceAsyncClient( credentials=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 = asset_service.ExportIamPolicyAnalysisRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.export_iam_policy_analysis), "__call__" + type(client.transport.export_iam_policy_analysis), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -620,12 +631,17 @@ async def test_export_iam_policy_analysis_async(transport: str = "grpc_asyncio") assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.ExportIamPolicyAnalysisRequest() # Establish that the response is the type that we expect. assert isinstance(response, future.Future) +@pytest.mark.asyncio +async def test_export_iam_policy_analysis_async_from_dict(): + await test_export_iam_policy_analysis_async(request_type=dict) + + def test_export_iam_policy_analysis_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -636,7 +652,7 @@ def test_export_iam_policy_analysis_field_headers(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.export_iam_policy_analysis), "__call__" + type(client.transport.export_iam_policy_analysis), "__call__" ) as call: call.return_value = operations_pb2.Operation(name="operations/op") @@ -666,7 +682,7 @@ async def test_export_iam_policy_analysis_field_headers_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.export_iam_policy_analysis), "__call__" + type(client.transport.export_iam_policy_analysis), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") @@ -723,7 +739,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = AssetServiceClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -756,7 +772,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.AssetServiceGrpcTransport,) + assert isinstance(client.transport, transports.AssetServiceGrpcTransport,) def test_asset_service_base_transport_error(): @@ -856,7 +872,7 @@ def test_asset_service_host_no_port(): api_endpoint="cloudasset.googleapis.com" ), ) - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_host_with_port(): @@ -866,7 +882,7 @@ def test_asset_service_host_with_port(): api_endpoint="cloudasset.googleapis.com:8000" ), ) - assert client._transport._host == "cloudasset.googleapis.com:8000" + assert client.transport._host == "cloudasset.googleapis.com:8000" def test_asset_service_grpc_transport_channel(): @@ -878,6 +894,7 @@ def test_asset_service_grpc_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None def test_asset_service_grpc_asyncio_transport_channel(): @@ -889,6 +906,7 @@ def test_asset_service_grpc_asyncio_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None @pytest.mark.parametrize( @@ -931,6 +949,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_ quota_project_id=None, ) assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred @pytest.mark.parametrize( @@ -974,7 +993,7 @@ def test_asset_service_grpc_lro_client(): client = AssetServiceClient( credentials=credentials.AnonymousCredentials(), transport="grpc", ) - transport = client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsClient,) @@ -987,7 +1006,7 @@ def test_asset_service_grpc_lro_async_client(): client = AssetServiceAsyncClient( credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", ) - transport = client._client._transport + transport = client.transport # Ensure that we have a api-core operations client. assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,) @@ -996,6 +1015,107 @@ def test_asset_service_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client +def test_common_billing_account_path(): + billing_account = "squid" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AssetServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = AssetServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + + expected = "folders/{folder}".format(folder=folder,) + actual = AssetServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = AssetServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + + expected = "organizations/{organization}".format(organization=organization,) + actual = AssetServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = AssetServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + + expected = "projects/{project}".format(project=project,) + actual = AssetServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = AssetServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = AssetServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = AssetServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo() diff --git a/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py index 0d132d46..77efc366 100644 --- a/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py @@ -91,12 +91,12 @@ def test_asset_service_client_from_service_account_file(client_class): ) as factory: factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds client = client_class.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds + assert client.transport._credentials == creds - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_client_get_transport_class(): @@ -440,7 +440,7 @@ def test_list_assets( request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_assets), "__call__") as call: + with mock.patch.object(type(client.transport.list_assets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = asset_service.ListAssetsResponse( next_page_token="next_page_token_value", @@ -455,6 +455,7 @@ def test_list_assets( assert args[0] == asset_service.ListAssetsRequest() # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAssetsPager) assert response.next_page_token == "next_page_token_value" @@ -465,19 +466,19 @@ def test_list_assets_from_dict(): @pytest.mark.asyncio -async def test_list_assets_async(transport: str = "grpc_asyncio"): +async def test_list_assets_async( + transport: str = "grpc_asyncio", request_type=asset_service.ListAssetsRequest +): client = AssetServiceAsyncClient( credentials=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 = asset_service.ListAssetsRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_assets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_assets), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.ListAssetsResponse(next_page_token="next_page_token_value",) @@ -489,7 +490,7 @@ async def test_list_assets_async(transport: str = "grpc_asyncio"): assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == request + assert args[0] == asset_service.ListAssetsRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListAssetsAsyncPager) @@ -497,6 +498,11 @@ async def test_list_assets_async(transport: str = "grpc_asyncio"): assert response.next_page_token == "next_page_token_value" +@pytest.mark.asyncio +async def test_list_assets_async_from_dict(): + await test_list_assets_async(request_type=dict) + + def test_list_assets_field_headers(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) @@ -506,7 +512,7 @@ def test_list_assets_field_headers(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_assets), "__call__") as call: + with mock.patch.object(type(client.transport.list_assets), "__call__") as call: call.return_value = asset_service.ListAssetsResponse() client.list_assets(request) @@ -531,9 +537,7 @@ async def test_list_assets_field_headers_async(): request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_assets), "__call__" - ) as call: + with mock.patch.object(type(client.transport.list_assets), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( asset_service.ListAssetsResponse() ) @@ -554,7 +558,7 @@ def test_list_assets_pager(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_assets), "__call__") as call: + with mock.patch.object(type(client.transport.list_assets), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( asset_service.ListAssetsResponse( @@ -586,7 +590,7 @@ def test_list_assets_pages(): client = AssetServiceClient(credentials=credentials.AnonymousCredentials,) # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_assets), "__call__") as call: + with mock.patch.object(type(client.transport.list_assets), "__call__") as call: # Set the response to a series of pages. call.side_effect = ( asset_service.ListAssetsResponse( @@ -611,9 +615,7 @@ async def test_list_assets_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_assets), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_assets), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -644,9 +646,7 @@ async def test_list_assets_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_assets), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_assets), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -704,7 +704,7 @@ def test_transport_instance(): credentials=credentials.AnonymousCredentials(), ) client = AssetServiceClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -737,7 +737,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AssetServiceClient(credentials=credentials.AnonymousCredentials(),) - assert isinstance(client._transport, transports.AssetServiceGrpcTransport,) + assert isinstance(client.transport, transports.AssetServiceGrpcTransport,) def test_asset_service_base_transport_error(): @@ -829,7 +829,7 @@ def test_asset_service_host_no_port(): api_endpoint="cloudasset.googleapis.com" ), ) - assert client._transport._host == "cloudasset.googleapis.com:443" + assert client.transport._host == "cloudasset.googleapis.com:443" def test_asset_service_host_with_port(): @@ -839,7 +839,7 @@ def test_asset_service_host_with_port(): api_endpoint="cloudasset.googleapis.com:8000" ), ) - assert client._transport._host == "cloudasset.googleapis.com:8000" + assert client.transport._host == "cloudasset.googleapis.com:8000" def test_asset_service_grpc_transport_channel(): @@ -851,6 +851,7 @@ def test_asset_service_grpc_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None def test_asset_service_grpc_asyncio_transport_channel(): @@ -862,6 +863,7 @@ def test_asset_service_grpc_asyncio_transport_channel(): ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None @pytest.mark.parametrize( @@ -904,6 +906,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_ quota_project_id=None, ) assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred @pytest.mark.parametrize( @@ -943,6 +946,114 @@ def test_asset_service_transport_channel_mtls_with_adc(transport_class): assert transport.grpc_channel == mock_grpc_channel +def test_asset_path(): + + expected = "*".format() + actual = AssetServiceClient.asset_path() + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "squid" + + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AssetServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = AssetServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + + expected = "folders/{folder}".format(folder=folder,) + actual = AssetServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = AssetServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + + expected = "organizations/{organization}".format(organization=organization,) + actual = AssetServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = AssetServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + + expected = "projects/{project}".format(project=project,) + actual = AssetServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = AssetServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = AssetServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = AssetServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AssetServiceClient.parse_common_location_path(path) + assert expected == actual + + def test_client_withDEFAULT_CLIENT_INFO(): client_info = gapic_v1.client_info.ClientInfo()