diff --git a/.librarian/state.yaml b/.librarian/state.yaml index b4c49fac3775..b6b4fa66a52d 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1182,7 +1182,7 @@ libraries: tag_format: '{id}-v{version}' - id: google-cloud-cloudsecuritycompliance version: 0.3.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd + last_generated_commit: 72e7439c8e7e9986cf1865e337fc7c64ca5bda1f apis: - path: google/cloud/cloudsecuritycompliance/v1 service_config: cloudsecuritycompliance_v1.yaml diff --git a/packages/google-cloud-cloudsecuritycompliance/docs/cloudsecuritycompliance_v1/audit.rst b/packages/google-cloud-cloudsecuritycompliance/docs/cloudsecuritycompliance_v1/audit.rst new file mode 100644 index 000000000000..9001538cc8c6 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/docs/cloudsecuritycompliance_v1/audit.rst @@ -0,0 +1,10 @@ +Audit +----------------------- + +.. automodule:: google.cloud.cloudsecuritycompliance_v1.services.audit + :members: + :inherited-members: + +.. automodule:: google.cloud.cloudsecuritycompliance_v1.services.audit.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-cloudsecuritycompliance/docs/cloudsecuritycompliance_v1/cm_enrollment_service.rst b/packages/google-cloud-cloudsecuritycompliance/docs/cloudsecuritycompliance_v1/cm_enrollment_service.rst new file mode 100644 index 000000000000..dcba2781e0a7 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/docs/cloudsecuritycompliance_v1/cm_enrollment_service.rst @@ -0,0 +1,6 @@ +CmEnrollmentService +------------------------------------- + +.. automodule:: google.cloud.cloudsecuritycompliance_v1.services.cm_enrollment_service + :members: + :inherited-members: diff --git a/packages/google-cloud-cloudsecuritycompliance/docs/cloudsecuritycompliance_v1/services_.rst b/packages/google-cloud-cloudsecuritycompliance/docs/cloudsecuritycompliance_v1/services_.rst index 02018deefdac..80065d89c786 100644 --- a/packages/google-cloud-cloudsecuritycompliance/docs/cloudsecuritycompliance_v1/services_.rst +++ b/packages/google-cloud-cloudsecuritycompliance/docs/cloudsecuritycompliance_v1/services_.rst @@ -3,5 +3,7 @@ Services for Google Cloud Cloudsecuritycompliance v1 API .. toctree:: :maxdepth: 2 + audit + cm_enrollment_service config deployment diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance/__init__.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance/__init__.py index 507db47d8d47..302f8b8c6666 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance/__init__.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance/__init__.py @@ -18,6 +18,16 @@ __version__ = package_version.__version__ +from google.cloud.cloudsecuritycompliance_v1.services.audit.async_client import ( + AuditAsyncClient, +) +from google.cloud.cloudsecuritycompliance_v1.services.audit.client import AuditClient +from google.cloud.cloudsecuritycompliance_v1.services.cm_enrollment_service.async_client import ( + CmEnrollmentServiceAsyncClient, +) +from google.cloud.cloudsecuritycompliance_v1.services.cm_enrollment_service.client import ( + CmEnrollmentServiceClient, +) from google.cloud.cloudsecuritycompliance_v1.services.config.async_client import ( ConfigAsyncClient, ) @@ -28,6 +38,31 @@ from google.cloud.cloudsecuritycompliance_v1.services.deployment.client import ( DeploymentClient, ) +from google.cloud.cloudsecuritycompliance_v1.types.audit import ( + BucketDestination, + CloudControlAuditDetails, + CloudControlGroupAuditDetails, + ComplianceState, + CreateFrameworkAuditRequest, + EvidenceDetails, + FindingDetails, + FrameworkAudit, + FrameworkAuditDestination, + GenerateFrameworkAuditScopeReportRequest, + GenerateFrameworkAuditScopeReportResponse, + GetFrameworkAuditRequest, + ListFrameworkAuditsRequest, + ListFrameworkAuditsResponse, + ObservationDetails, + ReportSummary, +) +from google.cloud.cloudsecuritycompliance_v1.types.cm_enrollment_service import ( + AuditConfig, + CalculateEffectiveCmEnrollmentRequest, + CalculateEffectiveCmEnrollmentResponse, + CmEnrollment, + UpdateCmEnrollmentRequest, +) from google.cloud.cloudsecuritycompliance_v1.types.common import ( AllowedValues, AttributeSubstitutionRule, @@ -36,6 +71,7 @@ CloudControlCategory, CloudControlDetails, CloudProvider, + ControlFamily, EnforcementMode, Framework, FrameworkCategory, @@ -48,6 +84,7 @@ ParamValue, PlaceholderSubstitutionRule, RegexpPattern, + RegulatoryControlResponsibilityType, Rule, RuleActionType, Severity, @@ -91,15 +128,41 @@ ) __all__ = ( + "AuditClient", + "AuditAsyncClient", + "CmEnrollmentServiceClient", + "CmEnrollmentServiceAsyncClient", "ConfigClient", "ConfigAsyncClient", "DeploymentClient", "DeploymentAsyncClient", + "BucketDestination", + "CloudControlAuditDetails", + "CloudControlGroupAuditDetails", + "CreateFrameworkAuditRequest", + "EvidenceDetails", + "FindingDetails", + "FrameworkAudit", + "FrameworkAuditDestination", + "GenerateFrameworkAuditScopeReportRequest", + "GenerateFrameworkAuditScopeReportResponse", + "GetFrameworkAuditRequest", + "ListFrameworkAuditsRequest", + "ListFrameworkAuditsResponse", + "ObservationDetails", + "ReportSummary", + "ComplianceState", + "AuditConfig", + "CalculateEffectiveCmEnrollmentRequest", + "CalculateEffectiveCmEnrollmentResponse", + "CmEnrollment", + "UpdateCmEnrollmentRequest", "AllowedValues", "AttributeSubstitutionRule", "CELExpression", "CloudControl", "CloudControlDetails", + "ControlFamily", "Framework", "FrameworkReference", "IntRange", @@ -117,6 +180,7 @@ "CloudProvider", "EnforcementMode", "FrameworkCategory", + "RegulatoryControlResponsibilityType", "RuleActionType", "Severity", "TargetResourceType", diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/__init__.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/__init__.py index a37739db483b..60e3e13d2a7e 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/__init__.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/__init__.py @@ -18,8 +18,38 @@ __version__ = package_version.__version__ +from .services.audit import AuditAsyncClient, AuditClient +from .services.cm_enrollment_service import ( + CmEnrollmentServiceAsyncClient, + CmEnrollmentServiceClient, +) from .services.config import ConfigAsyncClient, ConfigClient from .services.deployment import DeploymentAsyncClient, DeploymentClient +from .types.audit import ( + BucketDestination, + CloudControlAuditDetails, + CloudControlGroupAuditDetails, + ComplianceState, + CreateFrameworkAuditRequest, + EvidenceDetails, + FindingDetails, + FrameworkAudit, + FrameworkAuditDestination, + GenerateFrameworkAuditScopeReportRequest, + GenerateFrameworkAuditScopeReportResponse, + GetFrameworkAuditRequest, + ListFrameworkAuditsRequest, + ListFrameworkAuditsResponse, + ObservationDetails, + ReportSummary, +) +from .types.cm_enrollment_service import ( + AuditConfig, + CalculateEffectiveCmEnrollmentRequest, + CalculateEffectiveCmEnrollmentResponse, + CmEnrollment, + UpdateCmEnrollmentRequest, +) from .types.common import ( AllowedValues, AttributeSubstitutionRule, @@ -28,6 +58,7 @@ CloudControlCategory, CloudControlDetails, CloudProvider, + ControlFamily, EnforcementMode, Framework, FrameworkCategory, @@ -40,6 +71,7 @@ ParamValue, PlaceholderSubstitutionRule, RegexpPattern, + RegulatoryControlResponsibilityType, Rule, RuleActionType, Severity, @@ -83,20 +115,34 @@ ) __all__ = ( + "AuditAsyncClient", + "CmEnrollmentServiceAsyncClient", "ConfigAsyncClient", "DeploymentAsyncClient", "AllowedValues", "AttributeSubstitutionRule", + "AuditClient", + "AuditConfig", + "BucketDestination", "CELExpression", + "CalculateEffectiveCmEnrollmentRequest", + "CalculateEffectiveCmEnrollmentResponse", "CloudControl", + "CloudControlAuditDetails", "CloudControlCategory", "CloudControlDeployment", "CloudControlDeploymentReference", "CloudControlDetails", + "CloudControlGroupAuditDetails", "CloudControlMetadata", "CloudProvider", + "CmEnrollment", + "CmEnrollmentServiceClient", + "ComplianceState", "ConfigClient", + "ControlFamily", "CreateCloudControlRequest", + "CreateFrameworkAuditRequest", "CreateFrameworkDeploymentRequest", "CreateFrameworkRequest", "DeleteCloudControlRequest", @@ -105,14 +151,21 @@ "DeploymentClient", "DeploymentState", "EnforcementMode", + "EvidenceDetails", + "FindingDetails", "FolderCreationConfig", "Framework", + "FrameworkAudit", + "FrameworkAuditDestination", "FrameworkCategory", "FrameworkDeployment", "FrameworkDeploymentReference", "FrameworkReference", + "GenerateFrameworkAuditScopeReportRequest", + "GenerateFrameworkAuditScopeReportResponse", "GetCloudControlDeploymentRequest", "GetCloudControlRequest", + "GetFrameworkAuditRequest", "GetFrameworkDeploymentRequest", "GetFrameworkRequest", "IntRange", @@ -120,10 +173,13 @@ "ListCloudControlDeploymentsResponse", "ListCloudControlsRequest", "ListCloudControlsResponse", + "ListFrameworkAuditsRequest", + "ListFrameworkAuditsResponse", "ListFrameworkDeploymentsRequest", "ListFrameworkDeploymentsResponse", "ListFrameworksRequest", "ListFrameworksResponse", + "ObservationDetails", "OperationMetadata", "ParamValue", "Parameter", @@ -132,6 +188,8 @@ "PlaceholderSubstitutionRule", "ProjectCreationConfig", "RegexpPattern", + "RegulatoryControlResponsibilityType", + "ReportSummary", "Rule", "RuleActionType", "Severity", @@ -140,6 +198,7 @@ "TargetResourceCreationConfig", "TargetResourceType", "UpdateCloudControlRequest", + "UpdateCmEnrollmentRequest", "UpdateFrameworkRequest", "Validation", ) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/gapic_metadata.json b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/gapic_metadata.json index 21872e68049e..cda696c6068c 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/gapic_metadata.json +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/gapic_metadata.json @@ -5,6 +5,134 @@ "protoPackage": "google.cloud.cloudsecuritycompliance.v1", "schema": "1.0", "services": { + "Audit": { + "clients": { + "grpc": { + "libraryClient": "AuditClient", + "rpcs": { + "CreateFrameworkAudit": { + "methods": [ + "create_framework_audit" + ] + }, + "GenerateFrameworkAuditScopeReport": { + "methods": [ + "generate_framework_audit_scope_report" + ] + }, + "GetFrameworkAudit": { + "methods": [ + "get_framework_audit" + ] + }, + "ListFrameworkAudits": { + "methods": [ + "list_framework_audits" + ] + } + } + }, + "grpc-async": { + "libraryClient": "AuditAsyncClient", + "rpcs": { + "CreateFrameworkAudit": { + "methods": [ + "create_framework_audit" + ] + }, + "GenerateFrameworkAuditScopeReport": { + "methods": [ + "generate_framework_audit_scope_report" + ] + }, + "GetFrameworkAudit": { + "methods": [ + "get_framework_audit" + ] + }, + "ListFrameworkAudits": { + "methods": [ + "list_framework_audits" + ] + } + } + }, + "rest": { + "libraryClient": "AuditClient", + "rpcs": { + "CreateFrameworkAudit": { + "methods": [ + "create_framework_audit" + ] + }, + "GenerateFrameworkAuditScopeReport": { + "methods": [ + "generate_framework_audit_scope_report" + ] + }, + "GetFrameworkAudit": { + "methods": [ + "get_framework_audit" + ] + }, + "ListFrameworkAudits": { + "methods": [ + "list_framework_audits" + ] + } + } + } + } + }, + "CmEnrollmentService": { + "clients": { + "grpc": { + "libraryClient": "CmEnrollmentServiceClient", + "rpcs": { + "CalculateEffectiveCmEnrollment": { + "methods": [ + "calculate_effective_cm_enrollment" + ] + }, + "UpdateCmEnrollment": { + "methods": [ + "update_cm_enrollment" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CmEnrollmentServiceAsyncClient", + "rpcs": { + "CalculateEffectiveCmEnrollment": { + "methods": [ + "calculate_effective_cm_enrollment" + ] + }, + "UpdateCmEnrollment": { + "methods": [ + "update_cm_enrollment" + ] + } + } + }, + "rest": { + "libraryClient": "CmEnrollmentServiceClient", + "rpcs": { + "CalculateEffectiveCmEnrollment": { + "methods": [ + "calculate_effective_cm_enrollment" + ] + }, + "UpdateCmEnrollment": { + "methods": [ + "update_cm_enrollment" + ] + } + } + } + } + }, "Config": { "clients": { "grpc": { diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/__init__.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/__init__.py new file mode 100644 index 000000000000..66e3b8729860 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import AuditAsyncClient +from .client import AuditClient + +__all__ = ( + "AuditClient", + "AuditAsyncClient", +) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/async_client.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/async_client.py new file mode 100644 index 000000000000..d14507caa644 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/async_client.py @@ -0,0 +1,1184 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import logging as std_logging +import re +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.cloud.cloudsecuritycompliance_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.services.audit import pagers +from google.cloud.cloudsecuritycompliance_v1.types import audit, common + +from .client import AuditClient +from .transports.base import DEFAULT_CLIENT_INFO, AuditTransport +from .transports.grpc_asyncio import AuditGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class AuditAsyncClient: + """Service describing handlers for resources""" + + _client: AuditClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AuditClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AuditClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = AuditClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = AuditClient._DEFAULT_UNIVERSE + + framework_audit_path = staticmethod(AuditClient.framework_audit_path) + parse_framework_audit_path = staticmethod(AuditClient.parse_framework_audit_path) + generate_framework_audit_scope_report_response_path = staticmethod( + AuditClient.generate_framework_audit_scope_report_response_path + ) + parse_generate_framework_audit_scope_report_response_path = staticmethod( + AuditClient.parse_generate_framework_audit_scope_report_response_path + ) + common_billing_account_path = staticmethod(AuditClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod( + AuditClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(AuditClient.common_folder_path) + parse_common_folder_path = staticmethod(AuditClient.parse_common_folder_path) + common_organization_path = staticmethod(AuditClient.common_organization_path) + parse_common_organization_path = staticmethod( + AuditClient.parse_common_organization_path + ) + common_project_path = staticmethod(AuditClient.common_project_path) + parse_common_project_path = staticmethod(AuditClient.parse_common_project_path) + common_location_path = staticmethod(AuditClient.common_location_path) + parse_common_location_path = staticmethod(AuditClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AuditAsyncClient: The constructed client. + """ + return AuditClient.from_service_account_info.__func__(AuditAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AuditAsyncClient: The constructed client. + """ + return AuditClient.from_service_account_file.__func__(AuditAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AuditClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AuditTransport: + """Returns the transport used by the client instance. + + Returns: + AuditTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AuditClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[str, AuditTransport, Callable[..., AuditTransport]] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the audit async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AuditTransport,Callable[..., AuditTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AuditTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AuditClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient`.", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "credentialsType": None, + }, + ) + + async def generate_framework_audit_scope_report( + self, + request: Optional[ + Union[audit.GenerateFrameworkAuditScopeReportRequest, dict] + ] = None, + *, + scope: Optional[str] = None, + report_format: Optional[ + audit.GenerateFrameworkAuditScopeReportRequest.Format + ] = None, + compliance_framework: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audit.GenerateFrameworkAuditScopeReportResponse: + r"""Generates an audit scope report for a framework. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + async def sample_generate_framework_audit_scope_report(): + # Create a client + client = cloudsecuritycompliance_v1.AuditAsyncClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.GenerateFrameworkAuditScopeReportRequest( + scope="scope_value", + report_format="ODF", + compliance_framework="compliance_framework_value", + ) + + # Make the request + response = await client.generate_framework_audit_scope_report(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportRequest, dict]]): + The request object. The request message for + [GenerateFrameworkAuditScopeReport][]. + scope (:class:`str`): + Required. The organization, folder or project for the + audit report. + + Supported formats are the following: + + - ``projects/{project_id}/locations/{location}`` + - ``folders/{folder_id}/locations/{location}`` + - ``organizations/{organization_id}/locations/{location}`` + + This corresponds to the ``scope`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + report_format (:class:`google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportRequest.Format`): + Required. The format that the scope + report bytes is returned in. + + This corresponds to the ``report_format`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + compliance_framework (:class:`str`): + Required. The compliance framework + that the scope report is generated for. + + This corresponds to the ``compliance_framework`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportResponse: + The response message for + [GenerateFrameworkAuditScopeReport][]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [scope, report_format, compliance_framework] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, audit.GenerateFrameworkAuditScopeReportRequest): + request = audit.GenerateFrameworkAuditScopeReportRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if scope is not None: + request.scope = scope + if report_format is not None: + request.report_format = report_format + if compliance_framework is not None: + request.compliance_framework = compliance_framework + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_framework_audit_scope_report + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("scope", request.scope),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_framework_audit( + self, + request: Optional[Union[audit.CreateFrameworkAuditRequest, dict]] = None, + *, + parent: Optional[str] = None, + framework_audit: Optional[audit.FrameworkAudit] = None, + framework_audit_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates an audit scope report for a framework. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + async def sample_create_framework_audit(): + # Create a client + client = cloudsecuritycompliance_v1.AuditAsyncClient() + + # Initialize request argument(s) + framework_audit = cloudsecuritycompliance_v1.FrameworkAudit() + framework_audit.framework_audit_destination.bucket.bucket_uri = "bucket_uri_value" + + request = cloudsecuritycompliance_v1.CreateFrameworkAuditRequest( + parent="parent_value", + framework_audit=framework_audit, + ) + + # Make the request + operation = client.create_framework_audit(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.CreateFrameworkAuditRequest, dict]]): + The request object. The request message for [CreateFrameworkAudit][]. + parent (:class:`str`): + Required. The parent resource where this framework audit + is created. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}`` + - ``folders/{folder_id}/locations/{location}`` + - ``projects/{project_id}/locations/{location}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + framework_audit (:class:`google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit`): + Required. The framework audit to + create. + + This corresponds to the ``framework_audit`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + framework_audit_id (:class:`str`): + Optional. The ID to use for the framework audit. The ID + becomes the final component of the framework audit's + full resource name. + + The ID must be between 4-63 characters, and valid + characters are ``\[a-z][0-9]-\``. + + This corresponds to the ``framework_audit_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit` + A framework audit. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, framework_audit, framework_audit_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, audit.CreateFrameworkAuditRequest): + request = audit.CreateFrameworkAuditRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if framework_audit is not None: + request.framework_audit = framework_audit + if framework_audit_id is not None: + request.framework_audit_id = framework_audit_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_framework_audit + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + audit.FrameworkAudit, + metadata_type=common.OperationMetadata, + ) + + # Done; return the response. + return response + + async def list_framework_audits( + self, + request: Optional[Union[audit.ListFrameworkAuditsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListFrameworkAuditsAsyncPager: + r"""Lists the framework audits for a given organization, + folder, or project. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + async def sample_list_framework_audits(): + # Create a client + client = cloudsecuritycompliance_v1.AuditAsyncClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.ListFrameworkAuditsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_framework_audits(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsRequest, dict]]): + The request object. The request message for [ListFrameworkAudits][]. + parent (:class:`str`): + Required. The parent resource where the framework audits + are listed. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}`` + - ``folders/{folder_id}/locations/{location}`` + - ``projects/{project_id}/locations/{location}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.cloudsecuritycompliance_v1.services.audit.pagers.ListFrameworkAuditsAsyncPager: + The response message for [ListFrameworkAudits][]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, audit.ListFrameworkAuditsRequest): + request = audit.ListFrameworkAuditsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_framework_audits + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListFrameworkAuditsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_framework_audit( + self, + request: Optional[Union[audit.GetFrameworkAuditRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audit.FrameworkAudit: + r"""Gets the details for a framework audit. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + async def sample_get_framework_audit(): + # Create a client + client = cloudsecuritycompliance_v1.AuditAsyncClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.GetFrameworkAuditRequest( + name="name_value", + ) + + # Make the request + response = await client.get_framework_audit(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.GetFrameworkAuditRequest, dict]]): + The request object. The request message for [GetFrameworkAudit][]. + name (:class:`str`): + Required. The name of the framework audit to retrieve. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}/frameworkAudits/{frameworkAuditName}`` + - ``folders/{folder_id}/locations/{location}/frameworkAudits/{frameworkAuditName}`` + - ``projects/{project_id}/locations/{location}/frameworkAudits/{frameworkAuditName}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit: + A framework audit. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, audit.GetFrameworkAuditRequest): + request = audit.GetFrameworkAuditRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.get_framework_audit + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_operation( + self, + request: Optional[operations_pb2.DeleteOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Deletes a long-running operation. + + This method indicates that the client is no longer interested + in the operation result. It does not cancel the operation. + If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.delete_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.Location: + Location object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_location] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_locations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AuditAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AuditAsyncClient",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/client.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/client.py new file mode 100644 index 000000000000..851fe570ed90 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/client.py @@ -0,0 +1,1642 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.cloud.cloudsecuritycompliance_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.services.audit import pagers +from google.cloud.cloudsecuritycompliance_v1.types import audit, common + +from .transports.base import DEFAULT_CLIENT_INFO, AuditTransport +from .transports.grpc import AuditGrpcTransport +from .transports.grpc_asyncio import AuditGrpcAsyncIOTransport +from .transports.rest import AuditRestTransport + + +class AuditClientMeta(type): + """Metaclass for the Audit client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = OrderedDict() # type: Dict[str, Type[AuditTransport]] + _transport_registry["grpc"] = AuditGrpcTransport + _transport_registry["grpc_asyncio"] = AuditGrpcAsyncIOTransport + _transport_registry["rest"] = AuditRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AuditTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AuditClient(metaclass=AuditClientMeta): + """Service describing handlers for resources""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "cloudsecuritycompliance.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "cloudsecuritycompliance.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AuditClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AuditClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AuditTransport: + """Returns the transport used by the client instance. + + Returns: + AuditTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def framework_audit_path( + project: str, + location: str, + framework_audit: str, + ) -> str: + """Returns a fully-qualified framework_audit string.""" + return "projects/{project}/locations/{location}/frameworkAudits/{framework_audit}".format( + project=project, + location=location, + framework_audit=framework_audit, + ) + + @staticmethod + def parse_framework_audit_path(path: str) -> Dict[str, str]: + """Parses a framework_audit path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/frameworkAudits/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def generate_framework_audit_scope_report_response_path( + project: str, + location: str, + generate_framework_audit_scope_report_response: str, + ) -> str: + """Returns a fully-qualified generate_framework_audit_scope_report_response string.""" + return "projects/{project}/locations/{location}/frameworkAuditScopeReports/{generate_framework_audit_scope_report_response}".format( + project=project, + location=location, + generate_framework_audit_scope_report_response=generate_framework_audit_scope_report_response, + ) + + @staticmethod + def parse_generate_framework_audit_scope_report_response_path( + path: str, + ) -> Dict[str, str]: + """Parses a generate_framework_audit_scope_report_response path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/frameworkAuditScopeReports/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AuditClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AuditClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = AuditClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AuditClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[str, AuditTransport, Callable[..., AuditTransport]] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the audit client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AuditTransport,Callable[..., AuditTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AuditTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AuditClient._read_environment_variables() + self._client_cert_source = AuditClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = AuditClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + + api_key_value = getattr(self._client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AuditTransport) + if transport_provided: + # transport is a AuditTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AuditTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = self._api_endpoint or AuditClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AuditTransport], Callable[..., AuditTransport] + ] = ( + AuditClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AuditTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.cloudsecuritycompliance_v1.AuditClient`.", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "credentialsType": None, + }, + ) + + def generate_framework_audit_scope_report( + self, + request: Optional[ + Union[audit.GenerateFrameworkAuditScopeReportRequest, dict] + ] = None, + *, + scope: Optional[str] = None, + report_format: Optional[ + audit.GenerateFrameworkAuditScopeReportRequest.Format + ] = None, + compliance_framework: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audit.GenerateFrameworkAuditScopeReportResponse: + r"""Generates an audit scope report for a framework. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + def sample_generate_framework_audit_scope_report(): + # Create a client + client = cloudsecuritycompliance_v1.AuditClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.GenerateFrameworkAuditScopeReportRequest( + scope="scope_value", + report_format="ODF", + compliance_framework="compliance_framework_value", + ) + + # Make the request + response = client.generate_framework_audit_scope_report(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportRequest, dict]): + The request object. The request message for + [GenerateFrameworkAuditScopeReport][]. + scope (str): + Required. The organization, folder or project for the + audit report. + + Supported formats are the following: + + - ``projects/{project_id}/locations/{location}`` + - ``folders/{folder_id}/locations/{location}`` + - ``organizations/{organization_id}/locations/{location}`` + + This corresponds to the ``scope`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + report_format (google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportRequest.Format): + Required. The format that the scope + report bytes is returned in. + + This corresponds to the ``report_format`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + compliance_framework (str): + Required. The compliance framework + that the scope report is generated for. + + This corresponds to the ``compliance_framework`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportResponse: + The response message for + [GenerateFrameworkAuditScopeReport][]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [scope, report_format, compliance_framework] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, audit.GenerateFrameworkAuditScopeReportRequest): + request = audit.GenerateFrameworkAuditScopeReportRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if scope is not None: + request.scope = scope + if report_format is not None: + request.report_format = report_format + if compliance_framework is not None: + request.compliance_framework = compliance_framework + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_framework_audit_scope_report + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("scope", request.scope),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_framework_audit( + self, + request: Optional[Union[audit.CreateFrameworkAuditRequest, dict]] = None, + *, + parent: Optional[str] = None, + framework_audit: Optional[audit.FrameworkAudit] = None, + framework_audit_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Creates an audit scope report for a framework. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + def sample_create_framework_audit(): + # Create a client + client = cloudsecuritycompliance_v1.AuditClient() + + # Initialize request argument(s) + framework_audit = cloudsecuritycompliance_v1.FrameworkAudit() + framework_audit.framework_audit_destination.bucket.bucket_uri = "bucket_uri_value" + + request = cloudsecuritycompliance_v1.CreateFrameworkAuditRequest( + parent="parent_value", + framework_audit=framework_audit, + ) + + # Make the request + operation = client.create_framework_audit(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.cloudsecuritycompliance_v1.types.CreateFrameworkAuditRequest, dict]): + The request object. The request message for [CreateFrameworkAudit][]. + parent (str): + Required. The parent resource where this framework audit + is created. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}`` + - ``folders/{folder_id}/locations/{location}`` + - ``projects/{project_id}/locations/{location}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + framework_audit (google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit): + Required. The framework audit to + create. + + This corresponds to the ``framework_audit`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + framework_audit_id (str): + Optional. The ID to use for the framework audit. The ID + becomes the final component of the framework audit's + full resource name. + + The ID must be between 4-63 characters, and valid + characters are ``\[a-z][0-9]-\``. + + This corresponds to the ``framework_audit_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit` + A framework audit. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, framework_audit, framework_audit_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, audit.CreateFrameworkAuditRequest): + request = audit.CreateFrameworkAuditRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if framework_audit is not None: + request.framework_audit = framework_audit + if framework_audit_id is not None: + request.framework_audit_id = framework_audit_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_framework_audit] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + audit.FrameworkAudit, + metadata_type=common.OperationMetadata, + ) + + # Done; return the response. + return response + + def list_framework_audits( + self, + request: Optional[Union[audit.ListFrameworkAuditsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListFrameworkAuditsPager: + r"""Lists the framework audits for a given organization, + folder, or project. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + def sample_list_framework_audits(): + # Create a client + client = cloudsecuritycompliance_v1.AuditClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.ListFrameworkAuditsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_framework_audits(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsRequest, dict]): + The request object. The request message for [ListFrameworkAudits][]. + parent (str): + Required. The parent resource where the framework audits + are listed. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}`` + - ``folders/{folder_id}/locations/{location}`` + - ``projects/{project_id}/locations/{location}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.cloudsecuritycompliance_v1.services.audit.pagers.ListFrameworkAuditsPager: + The response message for [ListFrameworkAudits][]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, audit.ListFrameworkAuditsRequest): + request = audit.ListFrameworkAuditsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_framework_audits] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListFrameworkAuditsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_framework_audit( + self, + request: Optional[Union[audit.GetFrameworkAuditRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audit.FrameworkAudit: + r"""Gets the details for a framework audit. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + def sample_get_framework_audit(): + # Create a client + client = cloudsecuritycompliance_v1.AuditClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.GetFrameworkAuditRequest( + name="name_value", + ) + + # Make the request + response = client.get_framework_audit(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.cloudsecuritycompliance_v1.types.GetFrameworkAuditRequest, dict]): + The request object. The request message for [GetFrameworkAudit][]. + name (str): + Required. The name of the framework audit to retrieve. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}/frameworkAudits/{frameworkAuditName}`` + - ``folders/{folder_id}/locations/{location}/frameworkAudits/{frameworkAuditName}`` + - ``projects/{project_id}/locations/{location}/frameworkAudits/{frameworkAuditName}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit: + A framework audit. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, audit.GetFrameworkAuditRequest): + request = audit.GetFrameworkAuditRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_framework_audit] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AuditClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def delete_operation( + self, + request: Optional[operations_pb2.DeleteOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Deletes a long-running operation. + + This method indicates that the client is no longer interested + in the operation result. It does not cancel the operation. + If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.Location: + Location object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_location] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_locations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AuditClient",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/pagers.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/pagers.py new file mode 100644 index 000000000000..1bbd4a9a1685 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/pagers.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.types import audit + + +class ListFrameworkAuditsPager: + """A pager for iterating through ``list_framework_audits`` requests. + + This class thinly wraps an initial + :class:`google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``framework_audits`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListFrameworkAudits`` requests and continue to iterate + through the ``framework_audits`` field on the + corresponding responses. + + All the usual :class:`google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., audit.ListFrameworkAuditsResponse], + request: audit.ListFrameworkAuditsRequest, + response: audit.ListFrameworkAuditsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsRequest): + The initial request object. + response (google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = audit.ListFrameworkAuditsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[audit.ListFrameworkAuditsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[audit.FrameworkAudit]: + for page in self.pages: + yield from page.framework_audits + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListFrameworkAuditsAsyncPager: + """A pager for iterating through ``list_framework_audits`` requests. + + This class thinly wraps an initial + :class:`google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``framework_audits`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListFrameworkAudits`` requests and continue to iterate + through the ``framework_audits`` field on the + corresponding responses. + + All the usual :class:`google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., Awaitable[audit.ListFrameworkAuditsResponse]], + request: audit.ListFrameworkAuditsRequest, + response: audit.ListFrameworkAuditsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsRequest): + The initial request object. + response (google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + self._method = method + self._request = audit.ListFrameworkAuditsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[audit.ListFrameworkAuditsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[audit.FrameworkAudit]: + async def async_generator(): + async for page in self.pages: + for response in page.framework_audits: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/README.rst b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/README.rst new file mode 100644 index 000000000000..59f784f5654c --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AuditTransport` is the ABC for all transports. +- public child `AuditGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AuditGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAuditRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AuditRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/__init__.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/__init__.py new file mode 100644 index 000000000000..b670ddba6121 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import AuditTransport +from .grpc import AuditGrpcTransport +from .grpc_asyncio import AuditGrpcAsyncIOTransport +from .rest import AuditRestInterceptor, AuditRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[AuditTransport]] +_transport_registry["grpc"] = AuditGrpcTransport +_transport_registry["grpc_asyncio"] = AuditGrpcAsyncIOTransport +_transport_registry["rest"] = AuditRestTransport + +__all__ = ( + "AuditTransport", + "AuditGrpcTransport", + "AuditGrpcAsyncIOTransport", + "AuditRestTransport", + "AuditRestInterceptor", +) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/base.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/base.py new file mode 100644 index 000000000000..0f0bd3117de4 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/base.py @@ -0,0 +1,323 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.cloud.cloudsecuritycompliance_v1 import gapic_version as package_version +from google.cloud.cloudsecuritycompliance_v1.types import audit + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AuditTransport(abc.ABC): + """Abstract transport class for Audit.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + DEFAULT_HOST: str = "cloudsecuritycompliance.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'cloudsecuritycompliance.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.generate_framework_audit_scope_report: gapic_v1.method.wrap_method( + self.generate_framework_audit_scope_report, + default_timeout=60.0, + client_info=client_info, + ), + self.create_framework_audit: gapic_v1.method.wrap_method( + self.create_framework_audit, + default_timeout=60.0, + client_info=client_info, + ), + self.list_framework_audits: gapic_v1.method.wrap_method( + self.list_framework_audits, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_framework_audit: gapic_v1.method.wrap_method( + self.get_framework_audit, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_location: gapic_v1.method.wrap_method( + self.get_location, + default_timeout=None, + client_info=client_info, + ), + self.list_locations: gapic_v1.method.wrap_method( + self.list_locations, + default_timeout=None, + client_info=client_info, + ), + self.cancel_operation: gapic_v1.method.wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.delete_operation: gapic_v1.method.wrap_method( + self.delete_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: gapic_v1.method.wrap_method( + self.list_operations, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def generate_framework_audit_scope_report( + self, + ) -> Callable[ + [audit.GenerateFrameworkAuditScopeReportRequest], + Union[ + audit.GenerateFrameworkAuditScopeReportResponse, + Awaitable[audit.GenerateFrameworkAuditScopeReportResponse], + ], + ]: + raise NotImplementedError() + + @property + def create_framework_audit( + self, + ) -> Callable[ + [audit.CreateFrameworkAuditRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def list_framework_audits( + self, + ) -> Callable[ + [audit.ListFrameworkAuditsRequest], + Union[ + audit.ListFrameworkAuditsResponse, + Awaitable[audit.ListFrameworkAuditsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_framework_audit( + self, + ) -> Callable[ + [audit.GetFrameworkAuditRequest], + Union[audit.FrameworkAudit, Awaitable[audit.FrameworkAudit]], + ]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None,]: + raise NotImplementedError() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None,]: + raise NotImplementedError() + + @property + def get_location( + self, + ) -> Callable[ + [locations_pb2.GetLocationRequest], + Union[locations_pb2.Location, Awaitable[locations_pb2.Location]], + ]: + raise NotImplementedError() + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], + Union[ + locations_pb2.ListLocationsResponse, + Awaitable[locations_pb2.ListLocationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AuditTransport",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/grpc.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/grpc.py new file mode 100644 index 000000000000..10d24a3cfd5d --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/grpc.py @@ -0,0 +1,570 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json +import logging as std_logging +import pickle +from typing import Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers, operations_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.types import audit + +from .base import DEFAULT_CLIENT_INFO, AuditTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AuditGrpcTransport(AuditTransport): + """gRPC backend transport for Audit. + + Service describing handlers for resources + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'cloudsecuritycompliance.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def generate_framework_audit_scope_report( + self, + ) -> Callable[ + [audit.GenerateFrameworkAuditScopeReportRequest], + audit.GenerateFrameworkAuditScopeReportResponse, + ]: + r"""Return a callable for the generate framework audit scope + report method over gRPC. + + Generates an audit scope report for a framework. + + Returns: + Callable[[~.GenerateFrameworkAuditScopeReportRequest], + ~.GenerateFrameworkAuditScopeReportResponse]: + 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 "generate_framework_audit_scope_report" not in self._stubs: + self._stubs[ + "generate_framework_audit_scope_report" + ] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.Audit/GenerateFrameworkAuditScopeReport", + request_serializer=audit.GenerateFrameworkAuditScopeReportRequest.serialize, + response_deserializer=audit.GenerateFrameworkAuditScopeReportResponse.deserialize, + ) + return self._stubs["generate_framework_audit_scope_report"] + + @property + def create_framework_audit( + self, + ) -> Callable[[audit.CreateFrameworkAuditRequest], operations_pb2.Operation]: + r"""Return a callable for the create framework audit method over gRPC. + + Creates an audit scope report for a framework. + + Returns: + Callable[[~.CreateFrameworkAuditRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_framework_audit" not in self._stubs: + self._stubs["create_framework_audit"] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.Audit/CreateFrameworkAudit", + request_serializer=audit.CreateFrameworkAuditRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_framework_audit"] + + @property + def list_framework_audits( + self, + ) -> Callable[ + [audit.ListFrameworkAuditsRequest], audit.ListFrameworkAuditsResponse + ]: + r"""Return a callable for the list framework audits method over gRPC. + + Lists the framework audits for a given organization, + folder, or project. + + Returns: + Callable[[~.ListFrameworkAuditsRequest], + ~.ListFrameworkAuditsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_framework_audits" not in self._stubs: + self._stubs["list_framework_audits"] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.Audit/ListFrameworkAudits", + request_serializer=audit.ListFrameworkAuditsRequest.serialize, + response_deserializer=audit.ListFrameworkAuditsResponse.deserialize, + ) + return self._stubs["list_framework_audits"] + + @property + def get_framework_audit( + self, + ) -> Callable[[audit.GetFrameworkAuditRequest], audit.FrameworkAudit]: + r"""Return a callable for the get framework audit method over gRPC. + + Gets the details for a framework audit. + + Returns: + Callable[[~.GetFrameworkAuditRequest], + ~.FrameworkAudit]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_framework_audit" not in self._stubs: + self._stubs["get_framework_audit"] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.Audit/GetFrameworkAudit", + request_serializer=audit.GetFrameworkAuditRequest.serialize, + response_deserializer=audit.FrameworkAudit.deserialize, + ) + return self._stubs["get_framework_audit"] + + def close(self): + self._logged_channel.close() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_locations" not in self._stubs: + self._stubs["list_locations"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_location" not in self._stubs: + self._stubs["get_location"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AuditGrpcTransport",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/grpc_asyncio.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/grpc_asyncio.py new file mode 100644 index 000000000000..42476cd5a877 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/grpc_asyncio.py @@ -0,0 +1,658 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import json +import logging as std_logging +import pickle +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message +import grpc # type: ignore +from grpc.experimental import aio # type: ignore +import proto # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.types import audit + +from .base import DEFAULT_CLIENT_INFO, AuditTransport +from .grpc import AuditGrpcTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AuditGrpcAsyncIOTransport(AuditTransport): + """gRPC AsyncIO backend transport for Audit. + + Service describing handlers for resources + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'cloudsecuritycompliance.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def generate_framework_audit_scope_report( + self, + ) -> Callable[ + [audit.GenerateFrameworkAuditScopeReportRequest], + Awaitable[audit.GenerateFrameworkAuditScopeReportResponse], + ]: + r"""Return a callable for the generate framework audit scope + report method over gRPC. + + Generates an audit scope report for a framework. + + Returns: + Callable[[~.GenerateFrameworkAuditScopeReportRequest], + Awaitable[~.GenerateFrameworkAuditScopeReportResponse]]: + 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 "generate_framework_audit_scope_report" not in self._stubs: + self._stubs[ + "generate_framework_audit_scope_report" + ] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.Audit/GenerateFrameworkAuditScopeReport", + request_serializer=audit.GenerateFrameworkAuditScopeReportRequest.serialize, + response_deserializer=audit.GenerateFrameworkAuditScopeReportResponse.deserialize, + ) + return self._stubs["generate_framework_audit_scope_report"] + + @property + def create_framework_audit( + self, + ) -> Callable[ + [audit.CreateFrameworkAuditRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the create framework audit method over gRPC. + + Creates an audit scope report for a framework. + + Returns: + Callable[[~.CreateFrameworkAuditRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_framework_audit" not in self._stubs: + self._stubs["create_framework_audit"] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.Audit/CreateFrameworkAudit", + request_serializer=audit.CreateFrameworkAuditRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_framework_audit"] + + @property + def list_framework_audits( + self, + ) -> Callable[ + [audit.ListFrameworkAuditsRequest], Awaitable[audit.ListFrameworkAuditsResponse] + ]: + r"""Return a callable for the list framework audits method over gRPC. + + Lists the framework audits for a given organization, + folder, or project. + + Returns: + Callable[[~.ListFrameworkAuditsRequest], + Awaitable[~.ListFrameworkAuditsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_framework_audits" not in self._stubs: + self._stubs["list_framework_audits"] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.Audit/ListFrameworkAudits", + request_serializer=audit.ListFrameworkAuditsRequest.serialize, + response_deserializer=audit.ListFrameworkAuditsResponse.deserialize, + ) + return self._stubs["list_framework_audits"] + + @property + def get_framework_audit( + self, + ) -> Callable[[audit.GetFrameworkAuditRequest], Awaitable[audit.FrameworkAudit]]: + r"""Return a callable for the get framework audit method over gRPC. + + Gets the details for a framework audit. + + Returns: + Callable[[~.GetFrameworkAuditRequest], + Awaitable[~.FrameworkAudit]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_framework_audit" not in self._stubs: + self._stubs["get_framework_audit"] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.Audit/GetFrameworkAudit", + request_serializer=audit.GetFrameworkAuditRequest.serialize, + response_deserializer=audit.FrameworkAudit.deserialize, + ) + return self._stubs["get_framework_audit"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.generate_framework_audit_scope_report: self._wrap_method( + self.generate_framework_audit_scope_report, + default_timeout=60.0, + client_info=client_info, + ), + self.create_framework_audit: self._wrap_method( + self.create_framework_audit, + default_timeout=60.0, + client_info=client_info, + ), + self.list_framework_audits: self._wrap_method( + self.list_framework_audits, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_framework_audit: self._wrap_method( + self.get_framework_audit, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_location: self._wrap_method( + self.get_location, + default_timeout=None, + client_info=client_info, + ), + self.list_locations: self._wrap_method( + self.list_locations, + default_timeout=None, + client_info=client_info, + ), + self.cancel_operation: self._wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.delete_operation: self._wrap_method( + self.delete_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: self._wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: self._wrap_method( + self.list_operations, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_locations" not in self._stubs: + self._stubs["list_locations"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_location" not in self._stubs: + self._stubs["get_location"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + + +__all__ = ("AuditGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/rest.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/rest.py new file mode 100644 index 000000000000..efbb42fb7ce5 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/rest.py @@ -0,0 +1,2067 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, operations_v1, rest_helpers, rest_streaming +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.cloud.cloudsecuritycompliance_v1.types import audit + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAuditRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AuditRestInterceptor: + """Interceptor for Audit. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the AuditRestTransport. + + .. code-block:: python + class MyCustomAuditInterceptor(AuditRestInterceptor): + def pre_create_framework_audit(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_framework_audit(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_generate_framework_audit_scope_report(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_generate_framework_audit_scope_report(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_framework_audit(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_framework_audit(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_framework_audits(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_framework_audits(self, response): + logging.log(f"Received response: {response}") + return response + + transport = AuditRestTransport(interceptor=MyCustomAuditInterceptor()) + client = AuditClient(transport=transport) + + + """ + + def pre_create_framework_audit( + self, + request: audit.CreateFrameworkAuditRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + audit.CreateFrameworkAuditRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for create_framework_audit + + Override in a subclass to manipulate the request or metadata + before they are sent to the Audit server. + """ + return request, metadata + + def post_create_framework_audit( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_framework_audit + + DEPRECATED. Please use the `post_create_framework_audit_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Audit server but before + it is returned to user code. This `post_create_framework_audit` interceptor runs + before the `post_create_framework_audit_with_metadata` interceptor. + """ + return response + + def post_create_framework_audit_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_framework_audit + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Audit server but before it is returned to user code. + + We recommend only using this `post_create_framework_audit_with_metadata` + interceptor in new development instead of the `post_create_framework_audit` interceptor. + When both interceptors are used, this `post_create_framework_audit_with_metadata` interceptor runs after the + `post_create_framework_audit` interceptor. The (possibly modified) response returned by + `post_create_framework_audit` will be passed to + `post_create_framework_audit_with_metadata`. + """ + return response, metadata + + def pre_generate_framework_audit_scope_report( + self, + request: audit.GenerateFrameworkAuditScopeReportRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + audit.GenerateFrameworkAuditScopeReportRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for generate_framework_audit_scope_report + + Override in a subclass to manipulate the request or metadata + before they are sent to the Audit server. + """ + return request, metadata + + def post_generate_framework_audit_scope_report( + self, response: audit.GenerateFrameworkAuditScopeReportResponse + ) -> audit.GenerateFrameworkAuditScopeReportResponse: + """Post-rpc interceptor for generate_framework_audit_scope_report + + DEPRECATED. Please use the `post_generate_framework_audit_scope_report_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Audit server but before + it is returned to user code. This `post_generate_framework_audit_scope_report` interceptor runs + before the `post_generate_framework_audit_scope_report_with_metadata` interceptor. + """ + return response + + def post_generate_framework_audit_scope_report_with_metadata( + self, + response: audit.GenerateFrameworkAuditScopeReportResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + audit.GenerateFrameworkAuditScopeReportResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for generate_framework_audit_scope_report + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Audit server but before it is returned to user code. + + We recommend only using this `post_generate_framework_audit_scope_report_with_metadata` + interceptor in new development instead of the `post_generate_framework_audit_scope_report` interceptor. + When both interceptors are used, this `post_generate_framework_audit_scope_report_with_metadata` interceptor runs after the + `post_generate_framework_audit_scope_report` interceptor. The (possibly modified) response returned by + `post_generate_framework_audit_scope_report` will be passed to + `post_generate_framework_audit_scope_report_with_metadata`. + """ + return response, metadata + + def pre_get_framework_audit( + self, + request: audit.GetFrameworkAuditRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[audit.GetFrameworkAuditRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for get_framework_audit + + Override in a subclass to manipulate the request or metadata + before they are sent to the Audit server. + """ + return request, metadata + + def post_get_framework_audit( + self, response: audit.FrameworkAudit + ) -> audit.FrameworkAudit: + """Post-rpc interceptor for get_framework_audit + + DEPRECATED. Please use the `post_get_framework_audit_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Audit server but before + it is returned to user code. This `post_get_framework_audit` interceptor runs + before the `post_get_framework_audit_with_metadata` interceptor. + """ + return response + + def post_get_framework_audit_with_metadata( + self, + response: audit.FrameworkAudit, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[audit.FrameworkAudit, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_framework_audit + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Audit server but before it is returned to user code. + + We recommend only using this `post_get_framework_audit_with_metadata` + interceptor in new development instead of the `post_get_framework_audit` interceptor. + When both interceptors are used, this `post_get_framework_audit_with_metadata` interceptor runs after the + `post_get_framework_audit` interceptor. The (possibly modified) response returned by + `post_get_framework_audit` will be passed to + `post_get_framework_audit_with_metadata`. + """ + return response, metadata + + def pre_list_framework_audits( + self, + request: audit.ListFrameworkAuditsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + audit.ListFrameworkAuditsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_framework_audits + + Override in a subclass to manipulate the request or metadata + before they are sent to the Audit server. + """ + return request, metadata + + def post_list_framework_audits( + self, response: audit.ListFrameworkAuditsResponse + ) -> audit.ListFrameworkAuditsResponse: + """Post-rpc interceptor for list_framework_audits + + DEPRECATED. Please use the `post_list_framework_audits_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Audit server but before + it is returned to user code. This `post_list_framework_audits` interceptor runs + before the `post_list_framework_audits_with_metadata` interceptor. + """ + return response + + def post_list_framework_audits_with_metadata( + self, + response: audit.ListFrameworkAuditsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + audit.ListFrameworkAuditsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_framework_audits + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Audit server but before it is returned to user code. + + We recommend only using this `post_list_framework_audits_with_metadata` + interceptor in new development instead of the `post_list_framework_audits` interceptor. + When both interceptors are used, this `post_list_framework_audits_with_metadata` interceptor runs after the + `post_list_framework_audits` interceptor. The (possibly modified) response returned by + `post_list_framework_audits` will be passed to + `post_list_framework_audits_with_metadata`. + """ + return response, metadata + + def pre_get_location( + self, + request: locations_pb2.GetLocationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + locations_pb2.GetLocationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_location + + Override in a subclass to manipulate the request or metadata + before they are sent to the Audit server. + """ + return request, metadata + + def post_get_location( + self, response: locations_pb2.Location + ) -> locations_pb2.Location: + """Post-rpc interceptor for get_location + + Override in a subclass to manipulate the response + after it is returned by the Audit server but before + it is returned to user code. + """ + return response + + def pre_list_locations( + self, + request: locations_pb2.ListLocationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + locations_pb2.ListLocationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_locations + + Override in a subclass to manipulate the request or metadata + before they are sent to the Audit server. + """ + return request, metadata + + def post_list_locations( + self, response: locations_pb2.ListLocationsResponse + ) -> locations_pb2.ListLocationsResponse: + """Post-rpc interceptor for list_locations + + Override in a subclass to manipulate the response + after it is returned by the Audit server but before + it is returned to user code. + """ + return response + + def pre_cancel_operation( + self, + request: operations_pb2.CancelOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.CancelOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Audit server. + """ + return request, metadata + + def post_cancel_operation(self, response: None) -> None: + """Post-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the response + after it is returned by the Audit server but before + it is returned to user code. + """ + return response + + def pre_delete_operation( + self, + request: operations_pb2.DeleteOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.DeleteOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for delete_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Audit server. + """ + return request, metadata + + def post_delete_operation(self, response: None) -> None: + """Post-rpc interceptor for delete_operation + + Override in a subclass to manipulate the response + after it is returned by the Audit server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Audit server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the Audit server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.ListOperationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the Audit server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the Audit server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class AuditRestStub: + _session: AuthorizedSession + _host: str + _interceptor: AuditRestInterceptor + + +class AuditRestTransport(_BaseAuditRestTransport): + """REST backend synchronous transport for Audit. + + Service describing handlers for resources + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[AuditRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'cloudsecuritycompliance.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or AuditRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.CancelOperation": [ + { + "method": "post", + "uri": "/v1/{name=organizations/*/locations/*/operations/*}:cancel", + "body": "*", + }, + ], + "google.longrunning.Operations.DeleteOperation": [ + { + "method": "delete", + "uri": "/v1/{name=organizations/*/locations/*/operations/*}", + }, + ], + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v1/{name=organizations/*/locations/*/operations/*}", + }, + ], + "google.longrunning.Operations.ListOperations": [ + { + "method": "get", + "uri": "/v1/{name=organizations/*/locations/*}/operations", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _CreateFrameworkAudit( + _BaseAuditRestTransport._BaseCreateFrameworkAudit, AuditRestStub + ): + def __hash__(self): + return hash("AuditRestTransport.CreateFrameworkAudit") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: audit.CreateFrameworkAuditRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create framework audit method over HTTP. + + Args: + request (~.audit.CreateFrameworkAuditRequest): + The request object. The request message for [CreateFrameworkAudit][]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = ( + _BaseAuditRestTransport._BaseCreateFrameworkAudit._get_http_options() + ) + + request, metadata = self._interceptor.pre_create_framework_audit( + request, metadata + ) + transcoded_request = _BaseAuditRestTransport._BaseCreateFrameworkAudit._get_transcoded_request( + http_options, request + ) + + body = _BaseAuditRestTransport._BaseCreateFrameworkAudit._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseAuditRestTransport._BaseCreateFrameworkAudit._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.AuditClient.CreateFrameworkAudit", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "CreateFrameworkAudit", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuditRestTransport._CreateFrameworkAudit._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_framework_audit(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_framework_audit_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.AuditClient.create_framework_audit", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "CreateFrameworkAudit", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GenerateFrameworkAuditScopeReport( + _BaseAuditRestTransport._BaseGenerateFrameworkAuditScopeReport, AuditRestStub + ): + def __hash__(self): + return hash("AuditRestTransport.GenerateFrameworkAuditScopeReport") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: audit.GenerateFrameworkAuditScopeReportRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audit.GenerateFrameworkAuditScopeReportResponse: + r"""Call the generate framework audit + scope report method over HTTP. + + Args: + request (~.audit.GenerateFrameworkAuditScopeReportRequest): + The request object. The request message for + [GenerateFrameworkAuditScopeReport][]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.audit.GenerateFrameworkAuditScopeReportResponse: + The response message for + [GenerateFrameworkAuditScopeReport][]. + + """ + + http_options = ( + _BaseAuditRestTransport._BaseGenerateFrameworkAuditScopeReport._get_http_options() + ) + + ( + request, + metadata, + ) = self._interceptor.pre_generate_framework_audit_scope_report( + request, metadata + ) + transcoded_request = _BaseAuditRestTransport._BaseGenerateFrameworkAuditScopeReport._get_transcoded_request( + http_options, request + ) + + body = _BaseAuditRestTransport._BaseGenerateFrameworkAuditScopeReport._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseAuditRestTransport._BaseGenerateFrameworkAuditScopeReport._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.AuditClient.GenerateFrameworkAuditScopeReport", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "GenerateFrameworkAuditScopeReport", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + AuditRestTransport._GenerateFrameworkAuditScopeReport._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = audit.GenerateFrameworkAuditScopeReportResponse() + pb_resp = audit.GenerateFrameworkAuditScopeReportResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_generate_framework_audit_scope_report(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_generate_framework_audit_scope_report_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + audit.GenerateFrameworkAuditScopeReportResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.AuditClient.generate_framework_audit_scope_report", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "GenerateFrameworkAuditScopeReport", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetFrameworkAudit( + _BaseAuditRestTransport._BaseGetFrameworkAudit, AuditRestStub + ): + def __hash__(self): + return hash("AuditRestTransport.GetFrameworkAudit") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: audit.GetFrameworkAuditRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audit.FrameworkAudit: + r"""Call the get framework audit method over HTTP. + + Args: + request (~.audit.GetFrameworkAuditRequest): + The request object. The request message for [GetFrameworkAudit][]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.audit.FrameworkAudit: + A framework audit. + """ + + http_options = ( + _BaseAuditRestTransport._BaseGetFrameworkAudit._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_framework_audit( + request, metadata + ) + transcoded_request = ( + _BaseAuditRestTransport._BaseGetFrameworkAudit._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseAuditRestTransport._BaseGetFrameworkAudit._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.AuditClient.GetFrameworkAudit", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "GetFrameworkAudit", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuditRestTransport._GetFrameworkAudit._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = audit.FrameworkAudit() + pb_resp = audit.FrameworkAudit.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_framework_audit(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_framework_audit_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = audit.FrameworkAudit.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.AuditClient.get_framework_audit", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "GetFrameworkAudit", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListFrameworkAudits( + _BaseAuditRestTransport._BaseListFrameworkAudits, AuditRestStub + ): + def __hash__(self): + return hash("AuditRestTransport.ListFrameworkAudits") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: audit.ListFrameworkAuditsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audit.ListFrameworkAuditsResponse: + r"""Call the list framework audits method over HTTP. + + Args: + request (~.audit.ListFrameworkAuditsRequest): + The request object. The request message for [ListFrameworkAudits][]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.audit.ListFrameworkAuditsResponse: + The response message for [ListFrameworkAudits][]. + """ + + http_options = ( + _BaseAuditRestTransport._BaseListFrameworkAudits._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_framework_audits( + request, metadata + ) + transcoded_request = _BaseAuditRestTransport._BaseListFrameworkAudits._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = ( + _BaseAuditRestTransport._BaseListFrameworkAudits._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.AuditClient.ListFrameworkAudits", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "ListFrameworkAudits", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuditRestTransport._ListFrameworkAudits._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = audit.ListFrameworkAuditsResponse() + pb_resp = audit.ListFrameworkAuditsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_framework_audits(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_framework_audits_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = audit.ListFrameworkAuditsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.AuditClient.list_framework_audits", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "ListFrameworkAudits", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def create_framework_audit( + self, + ) -> Callable[[audit.CreateFrameworkAuditRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateFrameworkAudit(self._session, self._host, self._interceptor) # type: ignore + + @property + def generate_framework_audit_scope_report( + self, + ) -> Callable[ + [audit.GenerateFrameworkAuditScopeReportRequest], + audit.GenerateFrameworkAuditScopeReportResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GenerateFrameworkAuditScopeReport(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_framework_audit( + self, + ) -> Callable[[audit.GetFrameworkAuditRequest], audit.FrameworkAudit]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetFrameworkAudit(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_framework_audits( + self, + ) -> Callable[ + [audit.ListFrameworkAuditsRequest], audit.ListFrameworkAuditsResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListFrameworkAudits(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_location(self): + return self._GetLocation(self._session, self._host, self._interceptor) # type: ignore + + class _GetLocation(_BaseAuditRestTransport._BaseGetLocation, AuditRestStub): + def __hash__(self): + return hash("AuditRestTransport.GetLocation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: locations_pb2.GetLocationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Call the get location method over HTTP. + + Args: + request (locations_pb2.GetLocationRequest): + The request object for GetLocation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + locations_pb2.Location: Response from GetLocation method. + """ + + http_options = _BaseAuditRestTransport._BaseGetLocation._get_http_options() + + request, metadata = self._interceptor.pre_get_location(request, metadata) + transcoded_request = ( + _BaseAuditRestTransport._BaseGetLocation._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseAuditRestTransport._BaseGetLocation._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.AuditClient.GetLocation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "GetLocation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuditRestTransport._GetLocation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = locations_pb2.Location() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_location(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient.GetLocation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "GetLocation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def list_locations(self): + return self._ListLocations(self._session, self._host, self._interceptor) # type: ignore + + class _ListLocations(_BaseAuditRestTransport._BaseListLocations, AuditRestStub): + def __hash__(self): + return hash("AuditRestTransport.ListLocations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: locations_pb2.ListLocationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Call the list locations method over HTTP. + + Args: + request (locations_pb2.ListLocationsRequest): + The request object for ListLocations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + locations_pb2.ListLocationsResponse: Response from ListLocations method. + """ + + http_options = ( + _BaseAuditRestTransport._BaseListLocations._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_locations(request, metadata) + transcoded_request = ( + _BaseAuditRestTransport._BaseListLocations._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseAuditRestTransport._BaseListLocations._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.AuditClient.ListLocations", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "ListLocations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuditRestTransport._ListLocations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = locations_pb2.ListLocationsResponse() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_list_locations(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient.ListLocations", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "ListLocations", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def cancel_operation(self): + return self._CancelOperation(self._session, self._host, self._interceptor) # type: ignore + + class _CancelOperation(_BaseAuditRestTransport._BaseCancelOperation, AuditRestStub): + def __hash__(self): + return hash("AuditRestTransport.CancelOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: operations_pb2.CancelOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Call the cancel operation method over HTTP. + + Args: + request (operations_pb2.CancelOperationRequest): + The request object for CancelOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = ( + _BaseAuditRestTransport._BaseCancelOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_cancel_operation( + request, metadata + ) + transcoded_request = ( + _BaseAuditRestTransport._BaseCancelOperation._get_transcoded_request( + http_options, request + ) + ) + + body = _BaseAuditRestTransport._BaseCancelOperation._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = ( + _BaseAuditRestTransport._BaseCancelOperation._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.AuditClient.CancelOperation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "CancelOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuditRestTransport._CancelOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_cancel_operation(None) + + @property + def delete_operation(self): + return self._DeleteOperation(self._session, self._host, self._interceptor) # type: ignore + + class _DeleteOperation(_BaseAuditRestTransport._BaseDeleteOperation, AuditRestStub): + def __hash__(self): + return hash("AuditRestTransport.DeleteOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.DeleteOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Call the delete operation method over HTTP. + + Args: + request (operations_pb2.DeleteOperationRequest): + The request object for DeleteOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = ( + _BaseAuditRestTransport._BaseDeleteOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_delete_operation( + request, metadata + ) + transcoded_request = ( + _BaseAuditRestTransport._BaseDeleteOperation._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseAuditRestTransport._BaseDeleteOperation._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.AuditClient.DeleteOperation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "DeleteOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuditRestTransport._DeleteOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_delete_operation(None) + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(_BaseAuditRestTransport._BaseGetOperation, AuditRestStub): + def __hash__(self): + return hash("AuditRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = _BaseAuditRestTransport._BaseGetOperation._get_http_options() + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = ( + _BaseAuditRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseAuditRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.AuditClient.GetOperation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuditRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient.GetOperation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(_BaseAuditRestTransport._BaseListOperations, AuditRestStub): + def __hash__(self): + return hash("AuditRestTransport.ListOperations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options = ( + _BaseAuditRestTransport._BaseListOperations._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + transcoded_request = ( + _BaseAuditRestTransport._BaseListOperations._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseAuditRestTransport._BaseListOperations._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.AuditClient.ListOperations", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "ListOperations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AuditRestTransport._ListOperations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_list_operations(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient.ListOperations", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "rpcName": "ListOperations", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("AuditRestTransport",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/rest_base.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/rest_base.py new file mode 100644 index 000000000000..ea6f5cb6db30 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/audit/transports/rest_base.py @@ -0,0 +1,493 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.cloud.cloudsecuritycompliance_v1.types import audit + +from .base import DEFAULT_CLIENT_INFO, AuditTransport + + +class _BaseAuditRestTransport(AuditTransport): + """Base REST backend transport for Audit. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'cloudsecuritycompliance.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateFrameworkAudit: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=organizations/*/locations/*}/frameworkAudits", + "body": "framework_audit", + }, + { + "method": "post", + "uri": "/v1/{parent=folders/*/locations/*}/frameworkAudits", + "body": "framework_audit", + }, + { + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}/frameworkAudits", + "body": "framework_audit", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = audit.CreateFrameworkAuditRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAuditRestTransport._BaseCreateFrameworkAudit._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGenerateFrameworkAuditScopeReport: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{scope=folders/*/locations/*}/frameworkAuditScopeReports:generateFrameworkAuditScopeReport", + "body": "*", + }, + { + "method": "post", + "uri": "/v1/{scope=projects/*/locations/*}/frameworkAuditScopeReports:generateFrameworkAuditScopeReport", + "body": "*", + }, + { + "method": "post", + "uri": "/v1/{scope=organizations/*/locations/*}/frameworkAuditScopeReports:generateFrameworkAuditScopeReport", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = audit.GenerateFrameworkAuditScopeReportRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAuditRestTransport._BaseGenerateFrameworkAuditScopeReport._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetFrameworkAudit: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=organizations/*/locations/*/frameworkAudits/*}", + }, + { + "method": "get", + "uri": "/v1/{name=folders/*/locations/*/frameworkAudits/*}", + }, + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/frameworkAudits/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = audit.GetFrameworkAuditRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAuditRestTransport._BaseGetFrameworkAudit._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListFrameworkAudits: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=organizations/*/locations/*}/frameworkAudits", + }, + { + "method": "get", + "uri": "/v1/{parent=folders/*/locations/*}/frameworkAudits", + }, + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/frameworkAudits", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = audit.ListFrameworkAuditsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAuditRestTransport._BaseListFrameworkAudits._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetLocation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=organizations/*/locations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseListLocations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=organizations/*}/locations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseCancelOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{name=organizations/*/locations/*/operations/*}:cancel", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + body = json.dumps(transcoded_request["body"]) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseDeleteOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=organizations/*/locations/*/operations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=organizations/*/locations/*/operations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseListOperations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=organizations/*/locations/*}/operations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseAuditRestTransport",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/__init__.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/__init__.py new file mode 100644 index 000000000000..45ad39834aa5 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .async_client import CmEnrollmentServiceAsyncClient +from .client import CmEnrollmentServiceClient + +__all__ = ( + "CmEnrollmentServiceClient", + "CmEnrollmentServiceAsyncClient", +) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/async_client.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/async_client.py new file mode 100644 index 000000000000..7bb5d5abd16d --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/async_client.py @@ -0,0 +1,902 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import logging as std_logging +import re +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.cloud.cloudsecuritycompliance_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.types import cm_enrollment_service + +from .client import CmEnrollmentServiceClient +from .transports.base import DEFAULT_CLIENT_INFO, CmEnrollmentServiceTransport +from .transports.grpc_asyncio import CmEnrollmentServiceGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class CmEnrollmentServiceAsyncClient: + """Service describing CmEnrollment related RPCs for + complianceManager. + """ + + _client: CmEnrollmentServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CmEnrollmentServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CmEnrollmentServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = CmEnrollmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = CmEnrollmentServiceClient._DEFAULT_UNIVERSE + + cm_enrollment_path = staticmethod(CmEnrollmentServiceClient.cm_enrollment_path) + parse_cm_enrollment_path = staticmethod( + CmEnrollmentServiceClient.parse_cm_enrollment_path + ) + common_billing_account_path = staticmethod( + CmEnrollmentServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CmEnrollmentServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(CmEnrollmentServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + CmEnrollmentServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CmEnrollmentServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CmEnrollmentServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(CmEnrollmentServiceClient.common_project_path) + parse_common_project_path = staticmethod( + CmEnrollmentServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(CmEnrollmentServiceClient.common_location_path) + parse_common_location_path = staticmethod( + CmEnrollmentServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CmEnrollmentServiceAsyncClient: The constructed client. + """ + return CmEnrollmentServiceClient.from_service_account_info.__func__(CmEnrollmentServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CmEnrollmentServiceAsyncClient: The constructed client. + """ + return CmEnrollmentServiceClient.from_service_account_file.__func__(CmEnrollmentServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CmEnrollmentServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CmEnrollmentServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CmEnrollmentServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CmEnrollmentServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CmEnrollmentServiceTransport, + Callable[..., CmEnrollmentServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the cm enrollment service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CmEnrollmentServiceTransport,Callable[..., CmEnrollmentServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CmEnrollmentServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CmEnrollmentServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient`.", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "universeDomain": getattr( + self._client._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._client._transport, "_credentials") + else { + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "credentialsType": None, + }, + ) + + async def update_cm_enrollment( + self, + request: Optional[ + Union[cm_enrollment_service.UpdateCmEnrollmentRequest, dict] + ] = None, + *, + cm_enrollment: Optional[cm_enrollment_service.CmEnrollment] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> cm_enrollment_service.CmEnrollment: + r"""Updates the Compliance Manager enrollment for a + resource to facilitate an audit. + Use this method to enroll a resource in Compliance + Manager or to create or update feature-specific + configurations. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + async def sample_update_cm_enrollment(): + # Create a client + client = cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.UpdateCmEnrollmentRequest( + ) + + # Make the request + response = await client.update_cm_enrollment(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.UpdateCmEnrollmentRequest, dict]]): + The request object. The request message for [UpdateCmEnrollment][]. + cm_enrollment (:class:`google.cloud.cloudsecuritycompliance_v1.types.CmEnrollment`): + Required. The Compliance Manager enrollment to update. + The ``name`` field is used to identify the settings that + you want to update. + + This corresponds to the ``cm_enrollment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. The list of fields that you + want to update. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.cloudsecuritycompliance_v1.types.CmEnrollment: + The settings for Compliance Manager + at a specific resource scope.= + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [cm_enrollment, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, cm_enrollment_service.UpdateCmEnrollmentRequest): + request = cm_enrollment_service.UpdateCmEnrollmentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if cm_enrollment is not None: + request.cm_enrollment = cm_enrollment + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.update_cm_enrollment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("cm_enrollment.name", request.cm_enrollment.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def calculate_effective_cm_enrollment( + self, + request: Optional[ + Union[cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse: + r"""Calculates the effective Compliance Manager + enrollment for a resource. An effective enrollment is + either a direct enrollment of a resource (if it exists), + or an enrollment of the closest parent of a resource + that's enrolled in Compliance Manager. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + async def sample_calculate_effective_cm_enrollment(): + # Create a client + client = cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.CalculateEffectiveCmEnrollmentRequest( + name="name_value", + ) + + # Make the request + response = await client.calculate_effective_cm_enrollment(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.CalculateEffectiveCmEnrollmentRequest, dict]]): + The request object. The request message for + [CalculateEffectiveCmEnrollment][]. + name (:class:`str`): + Required. The name of the Compliance Manager enrollment + to calculate. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}/cmEnrollment`` + - ``folders/{folder_id}/locations/{location}/cmEnrollment`` + - ``projects/{project_id}/locations/{location}/cmEnrollment`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.cloudsecuritycompliance_v1.types.CalculateEffectiveCmEnrollmentResponse: + The response message for + [CalculateEffectiveCmEnrollment][]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest + ): + request = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.calculate_effective_cm_enrollment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_operation( + self, + request: Optional[operations_pb2.DeleteOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Deletes a long-running operation. + + This method indicates that the client is no longer interested + in the operation result. It does not cancel the operation. + If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.delete_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.Location: + Location object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_location] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_locations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CmEnrollmentServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CmEnrollmentServiceAsyncClient",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/client.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/client.py new file mode 100644 index 000000000000..c04dd9569e00 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/client.py @@ -0,0 +1,1340 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.cloud.cloudsecuritycompliance_v1 import gapic_version as package_version + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.types import cm_enrollment_service + +from .transports.base import DEFAULT_CLIENT_INFO, CmEnrollmentServiceTransport +from .transports.grpc import CmEnrollmentServiceGrpcTransport +from .transports.grpc_asyncio import CmEnrollmentServiceGrpcAsyncIOTransport +from .transports.rest import CmEnrollmentServiceRestTransport + + +class CmEnrollmentServiceClientMeta(type): + """Metaclass for the CmEnrollmentService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CmEnrollmentServiceTransport]] + _transport_registry["grpc"] = CmEnrollmentServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CmEnrollmentServiceGrpcAsyncIOTransport + _transport_registry["rest"] = CmEnrollmentServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CmEnrollmentServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CmEnrollmentServiceClient(metaclass=CmEnrollmentServiceClientMeta): + """Service describing CmEnrollment related RPCs for + complianceManager. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "cloudsecuritycompliance.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "cloudsecuritycompliance.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CmEnrollmentServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CmEnrollmentServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CmEnrollmentServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CmEnrollmentServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def cm_enrollment_path( + organization: str, + location: str, + ) -> str: + """Returns a fully-qualified cm_enrollment string.""" + return "organizations/{organization}/locations/{location}/cmEnrollment".format( + organization=organization, + location=location, + ) + + @staticmethod + def parse_cm_enrollment_path(path: str) -> Dict[str, str]: + """Parses a cm_enrollment path into its component segments.""" + m = re.match( + r"^organizations/(?P.+?)/locations/(?P.+?)/cmEnrollment$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CmEnrollmentServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CmEnrollmentServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = CmEnrollmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], universe_domain_env: Optional[str] + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CmEnrollmentServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CmEnrollmentServiceTransport, + Callable[..., CmEnrollmentServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the cm enrollment service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CmEnrollmentServiceTransport,Callable[..., CmEnrollmentServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CmEnrollmentServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr(self._client_options, "universe_domain", None) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CmEnrollmentServiceClient._read_environment_variables() + self._client_cert_source = CmEnrollmentServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = CmEnrollmentServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER + # Setup logging. + client_logging.initialize_logging() + + api_key_value = getattr(self._client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, CmEnrollmentServiceTransport) + if transport_provided: + # transport is a CmEnrollmentServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CmEnrollmentServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CmEnrollmentServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CmEnrollmentServiceTransport], + Callable[..., CmEnrollmentServiceTransport], + ] = ( + CmEnrollmentServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., CmEnrollmentServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + if "async" not in str(self._transport): + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient`.", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "universeDomain": getattr( + self._transport._credentials, "universe_domain", "" + ), + "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", + "credentialsInfo": getattr( + self.transport._credentials, "get_cred_info", lambda: None + )(), + } + if hasattr(self._transport, "_credentials") + else { + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "credentialsType": None, + }, + ) + + def update_cm_enrollment( + self, + request: Optional[ + Union[cm_enrollment_service.UpdateCmEnrollmentRequest, dict] + ] = None, + *, + cm_enrollment: Optional[cm_enrollment_service.CmEnrollment] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> cm_enrollment_service.CmEnrollment: + r"""Updates the Compliance Manager enrollment for a + resource to facilitate an audit. + Use this method to enroll a resource in Compliance + Manager or to create or update feature-specific + configurations. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + def sample_update_cm_enrollment(): + # Create a client + client = cloudsecuritycompliance_v1.CmEnrollmentServiceClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.UpdateCmEnrollmentRequest( + ) + + # Make the request + response = client.update_cm_enrollment(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.cloudsecuritycompliance_v1.types.UpdateCmEnrollmentRequest, dict]): + The request object. The request message for [UpdateCmEnrollment][]. + cm_enrollment (google.cloud.cloudsecuritycompliance_v1.types.CmEnrollment): + Required. The Compliance Manager enrollment to update. + The ``name`` field is used to identify the settings that + you want to update. + + This corresponds to the ``cm_enrollment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields that you + want to update. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.cloudsecuritycompliance_v1.types.CmEnrollment: + The settings for Compliance Manager + at a specific resource scope.= + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [cm_enrollment, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, cm_enrollment_service.UpdateCmEnrollmentRequest): + request = cm_enrollment_service.UpdateCmEnrollmentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if cm_enrollment is not None: + request.cm_enrollment = cm_enrollment + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_cm_enrollment] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("cm_enrollment.name", request.cm_enrollment.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def calculate_effective_cm_enrollment( + self, + request: Optional[ + Union[cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse: + r"""Calculates the effective Compliance Manager + enrollment for a resource. An effective enrollment is + either a direct enrollment of a resource (if it exists), + or an enrollment of the closest parent of a resource + that's enrolled in Compliance Manager. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import cloudsecuritycompliance_v1 + + def sample_calculate_effective_cm_enrollment(): + # Create a client + client = cloudsecuritycompliance_v1.CmEnrollmentServiceClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.CalculateEffectiveCmEnrollmentRequest( + name="name_value", + ) + + # Make the request + response = client.calculate_effective_cm_enrollment(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.cloudsecuritycompliance_v1.types.CalculateEffectiveCmEnrollmentRequest, dict]): + The request object. The request message for + [CalculateEffectiveCmEnrollment][]. + name (str): + Required. The name of the Compliance Manager enrollment + to calculate. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}/cmEnrollment`` + - ``folders/{folder_id}/locations/{location}/cmEnrollment`` + - ``projects/{project_id}/locations/{location}/cmEnrollment`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.cloudsecuritycompliance_v1.types.CalculateEffectiveCmEnrollmentResponse: + The response message for + [CalculateEffectiveCmEnrollment][]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + 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." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest + ): + request = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.calculate_effective_cm_enrollment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CmEnrollmentServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def delete_operation( + self, + request: Optional[operations_pb2.DeleteOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Deletes a long-running operation. + + This method indicates that the client is no longer interested + in the operation result. It does not cancel the operation. + If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.DeleteOperationRequest`): + The request object. Request message for + `DeleteOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.DeleteOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.Location: + Location object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_location] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_locations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CmEnrollmentServiceClient",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/README.rst b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/README.rst new file mode 100644 index 000000000000..fcad50d7316c --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`CmEnrollmentServiceTransport` is the ABC for all transports. +- public child `CmEnrollmentServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `CmEnrollmentServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseCmEnrollmentServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `CmEnrollmentServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/__init__.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/__init__.py new file mode 100644 index 000000000000..d2f862b421d1 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import CmEnrollmentServiceTransport +from .grpc import CmEnrollmentServiceGrpcTransport +from .grpc_asyncio import CmEnrollmentServiceGrpcAsyncIOTransport +from .rest import CmEnrollmentServiceRestInterceptor, CmEnrollmentServiceRestTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CmEnrollmentServiceTransport]] +_transport_registry["grpc"] = CmEnrollmentServiceGrpcTransport +_transport_registry["grpc_asyncio"] = CmEnrollmentServiceGrpcAsyncIOTransport +_transport_registry["rest"] = CmEnrollmentServiceRestTransport + +__all__ = ( + "CmEnrollmentServiceTransport", + "CmEnrollmentServiceGrpcTransport", + "CmEnrollmentServiceGrpcAsyncIOTransport", + "CmEnrollmentServiceRestTransport", + "CmEnrollmentServiceRestInterceptor", +) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/base.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/base.py new file mode 100644 index 000000000000..412520a6e38c --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/base.py @@ -0,0 +1,290 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.cloud.cloudsecuritycompliance_v1 import gapic_version as package_version +from google.cloud.cloudsecuritycompliance_v1.types import cm_enrollment_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CmEnrollmentServiceTransport(abc.ABC): + """Abstract transport class for CmEnrollmentService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + DEFAULT_HOST: str = "cloudsecuritycompliance.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'cloudsecuritycompliance.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.update_cm_enrollment: gapic_v1.method.wrap_method( + self.update_cm_enrollment, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.calculate_effective_cm_enrollment: gapic_v1.method.wrap_method( + self.calculate_effective_cm_enrollment, + default_retry=retries.Retry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_location: gapic_v1.method.wrap_method( + self.get_location, + default_timeout=None, + client_info=client_info, + ), + self.list_locations: gapic_v1.method.wrap_method( + self.list_locations, + default_timeout=None, + client_info=client_info, + ), + self.cancel_operation: gapic_v1.method.wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.delete_operation: gapic_v1.method.wrap_method( + self.delete_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: gapic_v1.method.wrap_method( + self.list_operations, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def update_cm_enrollment( + self, + ) -> Callable[ + [cm_enrollment_service.UpdateCmEnrollmentRequest], + Union[ + cm_enrollment_service.CmEnrollment, + Awaitable[cm_enrollment_service.CmEnrollment], + ], + ]: + raise NotImplementedError() + + @property + def calculate_effective_cm_enrollment( + self, + ) -> Callable[ + [cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest], + Union[ + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse, + Awaitable[cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None,]: + raise NotImplementedError() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None,]: + raise NotImplementedError() + + @property + def get_location( + self, + ) -> Callable[ + [locations_pb2.GetLocationRequest], + Union[locations_pb2.Location, Awaitable[locations_pb2.Location]], + ]: + raise NotImplementedError() + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], + Union[ + locations_pb2.ListLocationsResponse, + Awaitable[locations_pb2.ListLocationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CmEnrollmentServiceTransport",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/grpc.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/grpc.py new file mode 100644 index 000000000000..e88207dfec9f --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/grpc.py @@ -0,0 +1,510 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json +import logging as std_logging +import pickle +from typing import Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.types import cm_enrollment_service + +from .base import DEFAULT_CLIENT_INFO, CmEnrollmentServiceTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = response.result() + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response for {client_call_details.method}.", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CmEnrollmentServiceGrpcTransport(CmEnrollmentServiceTransport): + """gRPC backend transport for CmEnrollmentService. + + Service describing CmEnrollment related RPCs for + complianceManager. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'cloudsecuritycompliance.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( + self._grpc_channel, self._interceptor + ) + + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def update_cm_enrollment( + self, + ) -> Callable[ + [cm_enrollment_service.UpdateCmEnrollmentRequest], + cm_enrollment_service.CmEnrollment, + ]: + r"""Return a callable for the update cm enrollment method over gRPC. + + Updates the Compliance Manager enrollment for a + resource to facilitate an audit. + Use this method to enroll a resource in Compliance + Manager or to create or update feature-specific + configurations. + + Returns: + Callable[[~.UpdateCmEnrollmentRequest], + ~.CmEnrollment]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_cm_enrollment" not in self._stubs: + self._stubs["update_cm_enrollment"] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService/UpdateCmEnrollment", + request_serializer=cm_enrollment_service.UpdateCmEnrollmentRequest.serialize, + response_deserializer=cm_enrollment_service.CmEnrollment.deserialize, + ) + return self._stubs["update_cm_enrollment"] + + @property + def calculate_effective_cm_enrollment( + self, + ) -> Callable[ + [cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest], + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse, + ]: + r"""Return a callable for the calculate effective cm + enrollment method over gRPC. + + Calculates the effective Compliance Manager + enrollment for a resource. An effective enrollment is + either a direct enrollment of a resource (if it exists), + or an enrollment of the closest parent of a resource + that's enrolled in Compliance Manager. + + Returns: + Callable[[~.CalculateEffectiveCmEnrollmentRequest], + ~.CalculateEffectiveCmEnrollmentResponse]: + 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 "calculate_effective_cm_enrollment" not in self._stubs: + self._stubs[ + "calculate_effective_cm_enrollment" + ] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService/CalculateEffectiveCmEnrollment", + request_serializer=cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest.serialize, + response_deserializer=cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse.deserialize, + ) + return self._stubs["calculate_effective_cm_enrollment"] + + def close(self): + self._logged_channel.close() + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_locations" not in self._stubs: + self._stubs["list_locations"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_location" not in self._stubs: + self._stubs["get_location"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CmEnrollmentServiceGrpcTransport",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/grpc_asyncio.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..b7f6a020b4cf --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/grpc_asyncio.py @@ -0,0 +1,586 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import json +import logging as std_logging +import pickle +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message +import grpc # type: ignore +from grpc.experimental import aio # type: ignore +import proto # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.types import cm_enrollment_service + +from .base import DEFAULT_CLIENT_INFO, CmEnrollmentServiceTransport +from .grpc import CmEnrollmentServiceGrpcTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientAIOInterceptor( + grpc.aio.UnaryUnaryClientInterceptor +): # pragma: NO COVER + async def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" + + request_metadata = { + key: value.decode("utf-8") if isinstance(value, bytes) else value + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": str(client_call_details.method), + "request": grpc_request, + "metadata": grpc_request["metadata"], + }, + ) + response = await continuation(client_call_details, request) + if logging_enabled: # pragma: NO COVER + response_metadata = await response.trailing_metadata() + # Convert gRPC metadata `` to list of tuples + metadata = ( + dict([(k, str(v)) for k, v in response_metadata]) + if response_metadata + else None + ) + result = await response + if isinstance(result, proto.Message): + response_payload = type(result).to_json(result) + elif isinstance(result, google.protobuf.message.Message): + response_payload = MessageToJson(result) + else: + response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" + grpc_response = { + "payload": response_payload, + "metadata": metadata, + "status": "OK", + } + _LOGGER.debug( + f"Received response to rpc {client_call_details.method}.", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CmEnrollmentServiceGrpcAsyncIOTransport(CmEnrollmentServiceTransport): + """gRPC AsyncIO backend transport for CmEnrollmentService. + + Service describing CmEnrollment related RPCs for + complianceManager. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'cloudsecuritycompliance.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + self._interceptor = _LoggingClientAIOInterceptor() + self._grpc_channel._unary_unary_interceptors.append(self._interceptor) + self._logged_channel = self._grpc_channel + self._wrap_with_kind = ( + "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + ) + # Wrap messages. This must be done after self._logged_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def update_cm_enrollment( + self, + ) -> Callable[ + [cm_enrollment_service.UpdateCmEnrollmentRequest], + Awaitable[cm_enrollment_service.CmEnrollment], + ]: + r"""Return a callable for the update cm enrollment method over gRPC. + + Updates the Compliance Manager enrollment for a + resource to facilitate an audit. + Use this method to enroll a resource in Compliance + Manager or to create or update feature-specific + configurations. + + Returns: + Callable[[~.UpdateCmEnrollmentRequest], + Awaitable[~.CmEnrollment]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_cm_enrollment" not in self._stubs: + self._stubs["update_cm_enrollment"] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService/UpdateCmEnrollment", + request_serializer=cm_enrollment_service.UpdateCmEnrollmentRequest.serialize, + response_deserializer=cm_enrollment_service.CmEnrollment.deserialize, + ) + return self._stubs["update_cm_enrollment"] + + @property + def calculate_effective_cm_enrollment( + self, + ) -> Callable[ + [cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest], + Awaitable[cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse], + ]: + r"""Return a callable for the calculate effective cm + enrollment method over gRPC. + + Calculates the effective Compliance Manager + enrollment for a resource. An effective enrollment is + either a direct enrollment of a resource (if it exists), + or an enrollment of the closest parent of a resource + that's enrolled in Compliance Manager. + + Returns: + Callable[[~.CalculateEffectiveCmEnrollmentRequest], + Awaitable[~.CalculateEffectiveCmEnrollmentResponse]]: + 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 "calculate_effective_cm_enrollment" not in self._stubs: + self._stubs[ + "calculate_effective_cm_enrollment" + ] = self._logged_channel.unary_unary( + "/google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService/CalculateEffectiveCmEnrollment", + request_serializer=cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest.serialize, + response_deserializer=cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse.deserialize, + ) + return self._stubs["calculate_effective_cm_enrollment"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.update_cm_enrollment: self._wrap_method( + self.update_cm_enrollment, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.calculate_effective_cm_enrollment: self._wrap_method( + self.calculate_effective_cm_enrollment, + default_retry=retries.AsyncRetry( + initial=1.0, + maximum=10.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.ServiceUnavailable, + ), + deadline=60.0, + ), + default_timeout=60.0, + client_info=client_info, + ), + self.get_location: self._wrap_method( + self.get_location, + default_timeout=None, + client_info=client_info, + ), + self.list_locations: self._wrap_method( + self.list_locations, + default_timeout=None, + client_info=client_info, + ), + self.cancel_operation: self._wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.delete_operation: self._wrap_method( + self.delete_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: self._wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: self._wrap_method( + self.list_operations, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + @property + def delete_operation( + self, + ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: + r"""Return a callable for the delete_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_operation" not in self._stubs: + self._stubs["delete_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/DeleteOperation", + request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["delete_operation"] + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_locations" not in self._stubs: + self._stubs["list_locations"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_location" not in self._stubs: + self._stubs["get_location"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + + +__all__ = ("CmEnrollmentServiceGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/rest.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/rest.py new file mode 100644 index 000000000000..b2b970056b1a --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/rest.py @@ -0,0 +1,1586 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.cloud.cloudsecuritycompliance_v1.types import cm_enrollment_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseCmEnrollmentServiceRestTransport + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CmEnrollmentServiceRestInterceptor: + """Interceptor for CmEnrollmentService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the CmEnrollmentServiceRestTransport. + + .. code-block:: python + class MyCustomCmEnrollmentServiceInterceptor(CmEnrollmentServiceRestInterceptor): + def pre_calculate_effective_cm_enrollment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_calculate_effective_cm_enrollment(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_cm_enrollment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_cm_enrollment(self, response): + logging.log(f"Received response: {response}") + return response + + transport = CmEnrollmentServiceRestTransport(interceptor=MyCustomCmEnrollmentServiceInterceptor()) + client = CmEnrollmentServiceClient(transport=transport) + + + """ + + def pre_calculate_effective_cm_enrollment( + self, + request: cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for calculate_effective_cm_enrollment + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmEnrollmentService server. + """ + return request, metadata + + def post_calculate_effective_cm_enrollment( + self, response: cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse + ) -> cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse: + """Post-rpc interceptor for calculate_effective_cm_enrollment + + DEPRECATED. Please use the `post_calculate_effective_cm_enrollment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CmEnrollmentService server but before + it is returned to user code. This `post_calculate_effective_cm_enrollment` interceptor runs + before the `post_calculate_effective_cm_enrollment_with_metadata` interceptor. + """ + return response + + def post_calculate_effective_cm_enrollment_with_metadata( + self, + response: cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for calculate_effective_cm_enrollment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CmEnrollmentService server but before it is returned to user code. + + We recommend only using this `post_calculate_effective_cm_enrollment_with_metadata` + interceptor in new development instead of the `post_calculate_effective_cm_enrollment` interceptor. + When both interceptors are used, this `post_calculate_effective_cm_enrollment_with_metadata` interceptor runs after the + `post_calculate_effective_cm_enrollment` interceptor. The (possibly modified) response returned by + `post_calculate_effective_cm_enrollment` will be passed to + `post_calculate_effective_cm_enrollment_with_metadata`. + """ + return response, metadata + + def pre_update_cm_enrollment( + self, + request: cm_enrollment_service.UpdateCmEnrollmentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cm_enrollment_service.UpdateCmEnrollmentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for update_cm_enrollment + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmEnrollmentService server. + """ + return request, metadata + + def post_update_cm_enrollment( + self, response: cm_enrollment_service.CmEnrollment + ) -> cm_enrollment_service.CmEnrollment: + """Post-rpc interceptor for update_cm_enrollment + + DEPRECATED. Please use the `post_update_cm_enrollment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CmEnrollmentService server but before + it is returned to user code. This `post_update_cm_enrollment` interceptor runs + before the `post_update_cm_enrollment_with_metadata` interceptor. + """ + return response + + def post_update_cm_enrollment_with_metadata( + self, + response: cm_enrollment_service.CmEnrollment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cm_enrollment_service.CmEnrollment, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_cm_enrollment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CmEnrollmentService server but before it is returned to user code. + + We recommend only using this `post_update_cm_enrollment_with_metadata` + interceptor in new development instead of the `post_update_cm_enrollment` interceptor. + When both interceptors are used, this `post_update_cm_enrollment_with_metadata` interceptor runs after the + `post_update_cm_enrollment` interceptor. The (possibly modified) response returned by + `post_update_cm_enrollment` will be passed to + `post_update_cm_enrollment_with_metadata`. + """ + return response, metadata + + def pre_get_location( + self, + request: locations_pb2.GetLocationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + locations_pb2.GetLocationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_location + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmEnrollmentService server. + """ + return request, metadata + + def post_get_location( + self, response: locations_pb2.Location + ) -> locations_pb2.Location: + """Post-rpc interceptor for get_location + + Override in a subclass to manipulate the response + after it is returned by the CmEnrollmentService server but before + it is returned to user code. + """ + return response + + def pre_list_locations( + self, + request: locations_pb2.ListLocationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + locations_pb2.ListLocationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_locations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmEnrollmentService server. + """ + return request, metadata + + def post_list_locations( + self, response: locations_pb2.ListLocationsResponse + ) -> locations_pb2.ListLocationsResponse: + """Post-rpc interceptor for list_locations + + Override in a subclass to manipulate the response + after it is returned by the CmEnrollmentService server but before + it is returned to user code. + """ + return response + + def pre_cancel_operation( + self, + request: operations_pb2.CancelOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.CancelOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmEnrollmentService server. + """ + return request, metadata + + def post_cancel_operation(self, response: None) -> None: + """Post-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the response + after it is returned by the CmEnrollmentService server but before + it is returned to user code. + """ + return response + + def pre_delete_operation( + self, + request: operations_pb2.DeleteOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.DeleteOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for delete_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmEnrollmentService server. + """ + return request, metadata + + def post_delete_operation(self, response: None) -> None: + """Post-rpc interceptor for delete_operation + + Override in a subclass to manipulate the response + after it is returned by the CmEnrollmentService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmEnrollmentService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the CmEnrollmentService server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.ListOperationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmEnrollmentService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the CmEnrollmentService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class CmEnrollmentServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: CmEnrollmentServiceRestInterceptor + + +class CmEnrollmentServiceRestTransport(_BaseCmEnrollmentServiceRestTransport): + """REST backend synchronous transport for CmEnrollmentService. + + Service describing CmEnrollment related RPCs for + complianceManager. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[CmEnrollmentServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'cloudsecuritycompliance.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or CmEnrollmentServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _CalculateEffectiveCmEnrollment( + _BaseCmEnrollmentServiceRestTransport._BaseCalculateEffectiveCmEnrollment, + CmEnrollmentServiceRestStub, + ): + def __hash__(self): + return hash( + "CmEnrollmentServiceRestTransport.CalculateEffectiveCmEnrollment" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse: + r"""Call the calculate effective cm + enrollment method over HTTP. + + Args: + request (~.cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest): + The request object. The request message for + [CalculateEffectiveCmEnrollment][]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse: + The response message for + [CalculateEffectiveCmEnrollment][]. + + """ + + http_options = ( + _BaseCmEnrollmentServiceRestTransport._BaseCalculateEffectiveCmEnrollment._get_http_options() + ) + + request, metadata = self._interceptor.pre_calculate_effective_cm_enrollment( + request, metadata + ) + transcoded_request = _BaseCmEnrollmentServiceRestTransport._BaseCalculateEffectiveCmEnrollment._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmEnrollmentServiceRestTransport._BaseCalculateEffectiveCmEnrollment._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.CalculateEffectiveCmEnrollment", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "CalculateEffectiveCmEnrollment", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CmEnrollmentServiceRestTransport._CalculateEffectiveCmEnrollment._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + pb_resp = cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse.pb( + resp + ) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_calculate_effective_cm_enrollment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_calculate_effective_cm_enrollment_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.calculate_effective_cm_enrollment", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "CalculateEffectiveCmEnrollment", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateCmEnrollment( + _BaseCmEnrollmentServiceRestTransport._BaseUpdateCmEnrollment, + CmEnrollmentServiceRestStub, + ): + def __hash__(self): + return hash("CmEnrollmentServiceRestTransport.UpdateCmEnrollment") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: cm_enrollment_service.UpdateCmEnrollmentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> cm_enrollment_service.CmEnrollment: + r"""Call the update cm enrollment method over HTTP. + + Args: + request (~.cm_enrollment_service.UpdateCmEnrollmentRequest): + The request object. The request message for [UpdateCmEnrollment][]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.cm_enrollment_service.CmEnrollment: + The settings for Compliance Manager + at a specific resource scope.= + + """ + + http_options = ( + _BaseCmEnrollmentServiceRestTransport._BaseUpdateCmEnrollment._get_http_options() + ) + + request, metadata = self._interceptor.pre_update_cm_enrollment( + request, metadata + ) + transcoded_request = _BaseCmEnrollmentServiceRestTransport._BaseUpdateCmEnrollment._get_transcoded_request( + http_options, request + ) + + body = _BaseCmEnrollmentServiceRestTransport._BaseUpdateCmEnrollment._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseCmEnrollmentServiceRestTransport._BaseUpdateCmEnrollment._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.UpdateCmEnrollment", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "UpdateCmEnrollment", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + CmEnrollmentServiceRestTransport._UpdateCmEnrollment._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = cm_enrollment_service.CmEnrollment() + pb_resp = cm_enrollment_service.CmEnrollment.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_cm_enrollment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_cm_enrollment_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = cm_enrollment_service.CmEnrollment.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.update_cm_enrollment", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "UpdateCmEnrollment", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def calculate_effective_cm_enrollment( + self, + ) -> Callable[ + [cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest], + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CalculateEffectiveCmEnrollment(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_cm_enrollment( + self, + ) -> Callable[ + [cm_enrollment_service.UpdateCmEnrollmentRequest], + cm_enrollment_service.CmEnrollment, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateCmEnrollment(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_location(self): + return self._GetLocation(self._session, self._host, self._interceptor) # type: ignore + + class _GetLocation( + _BaseCmEnrollmentServiceRestTransport._BaseGetLocation, + CmEnrollmentServiceRestStub, + ): + def __hash__(self): + return hash("CmEnrollmentServiceRestTransport.GetLocation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: locations_pb2.GetLocationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Call the get location method over HTTP. + + Args: + request (locations_pb2.GetLocationRequest): + The request object for GetLocation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + locations_pb2.Location: Response from GetLocation method. + """ + + http_options = ( + _BaseCmEnrollmentServiceRestTransport._BaseGetLocation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_location(request, metadata) + transcoded_request = _BaseCmEnrollmentServiceRestTransport._BaseGetLocation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmEnrollmentServiceRestTransport._BaseGetLocation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.GetLocation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "GetLocation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CmEnrollmentServiceRestTransport._GetLocation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = locations_pb2.Location() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_location(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient.GetLocation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "GetLocation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def list_locations(self): + return self._ListLocations(self._session, self._host, self._interceptor) # type: ignore + + class _ListLocations( + _BaseCmEnrollmentServiceRestTransport._BaseListLocations, + CmEnrollmentServiceRestStub, + ): + def __hash__(self): + return hash("CmEnrollmentServiceRestTransport.ListLocations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: locations_pb2.ListLocationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Call the list locations method over HTTP. + + Args: + request (locations_pb2.ListLocationsRequest): + The request object for ListLocations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + locations_pb2.ListLocationsResponse: Response from ListLocations method. + """ + + http_options = ( + _BaseCmEnrollmentServiceRestTransport._BaseListLocations._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_locations(request, metadata) + transcoded_request = _BaseCmEnrollmentServiceRestTransport._BaseListLocations._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmEnrollmentServiceRestTransport._BaseListLocations._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.ListLocations", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "ListLocations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CmEnrollmentServiceRestTransport._ListLocations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = locations_pb2.ListLocationsResponse() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_list_locations(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient.ListLocations", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "ListLocations", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def cancel_operation(self): + return self._CancelOperation(self._session, self._host, self._interceptor) # type: ignore + + class _CancelOperation( + _BaseCmEnrollmentServiceRestTransport._BaseCancelOperation, + CmEnrollmentServiceRestStub, + ): + def __hash__(self): + return hash("CmEnrollmentServiceRestTransport.CancelOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: operations_pb2.CancelOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Call the cancel operation method over HTTP. + + Args: + request (operations_pb2.CancelOperationRequest): + The request object for CancelOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = ( + _BaseCmEnrollmentServiceRestTransport._BaseCancelOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_cancel_operation( + request, metadata + ) + transcoded_request = _BaseCmEnrollmentServiceRestTransport._BaseCancelOperation._get_transcoded_request( + http_options, request + ) + + body = _BaseCmEnrollmentServiceRestTransport._BaseCancelOperation._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseCmEnrollmentServiceRestTransport._BaseCancelOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.CancelOperation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "CancelOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CmEnrollmentServiceRestTransport._CancelOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_cancel_operation(None) + + @property + def delete_operation(self): + return self._DeleteOperation(self._session, self._host, self._interceptor) # type: ignore + + class _DeleteOperation( + _BaseCmEnrollmentServiceRestTransport._BaseDeleteOperation, + CmEnrollmentServiceRestStub, + ): + def __hash__(self): + return hash("CmEnrollmentServiceRestTransport.DeleteOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.DeleteOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Call the delete operation method over HTTP. + + Args: + request (operations_pb2.DeleteOperationRequest): + The request object for DeleteOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = ( + _BaseCmEnrollmentServiceRestTransport._BaseDeleteOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_delete_operation( + request, metadata + ) + transcoded_request = _BaseCmEnrollmentServiceRestTransport._BaseDeleteOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmEnrollmentServiceRestTransport._BaseDeleteOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.DeleteOperation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "DeleteOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CmEnrollmentServiceRestTransport._DeleteOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_delete_operation(None) + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseCmEnrollmentServiceRestTransport._BaseGetOperation, + CmEnrollmentServiceRestStub, + ): + def __hash__(self): + return hash("CmEnrollmentServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseCmEnrollmentServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseCmEnrollmentServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmEnrollmentServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.GetOperation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CmEnrollmentServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations( + _BaseCmEnrollmentServiceRestTransport._BaseListOperations, + CmEnrollmentServiceRestStub, + ): + def __hash__(self): + return hash("CmEnrollmentServiceRestTransport.ListOperations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options = ( + _BaseCmEnrollmentServiceRestTransport._BaseListOperations._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + transcoded_request = _BaseCmEnrollmentServiceRestTransport._BaseListOperations._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmEnrollmentServiceRestTransport._BaseListOperations._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.ListOperations", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "ListOperations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CmEnrollmentServiceRestTransport._ListOperations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_list_operations(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient.ListOperations", + extra={ + "serviceName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "rpcName": "ListOperations", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("CmEnrollmentServiceRestTransport",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/rest_base.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/rest_base.py new file mode 100644 index 000000000000..04b1497d8c9a --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/cm_enrollment_service/transports/rest_base.py @@ -0,0 +1,373 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.cloud.cloudsecuritycompliance_v1.types import cm_enrollment_service + +from .base import DEFAULT_CLIENT_INFO, CmEnrollmentServiceTransport + + +class _BaseCmEnrollmentServiceRestTransport(CmEnrollmentServiceTransport): + """Base REST backend transport for CmEnrollmentService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "cloudsecuritycompliance.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'cloudsecuritycompliance.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCalculateEffectiveCmEnrollment: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=organizations/*/locations/*/cmEnrollment}:calculate", + }, + { + "method": "get", + "uri": "/v1/{name=folders/*/locations/*/cmEnrollment}:calculate", + }, + { + "method": "get", + "uri": "/v1/{name=projects/*/locations/*/cmEnrollment}:calculate", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCmEnrollmentServiceRestTransport._BaseCalculateEffectiveCmEnrollment._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateCmEnrollment: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{cm_enrollment.name=organizations/*/locations/*/cmEnrollment}", + "body": "cm_enrollment", + }, + { + "method": "patch", + "uri": "/v1/{cm_enrollment.name=folders/*/locations/*/cmEnrollment}", + "body": "cm_enrollment", + }, + { + "method": "patch", + "uri": "/v1/{cm_enrollment.name=projects/*/locations/*/cmEnrollment}", + "body": "cm_enrollment", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = cm_enrollment_service.UpdateCmEnrollmentRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCmEnrollmentServiceRestTransport._BaseUpdateCmEnrollment._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetLocation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=organizations/*/locations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseListLocations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=organizations/*}/locations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseCancelOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{name=organizations/*/locations/*/operations/*}:cancel", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + body = json.dumps(transcoded_request["body"]) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseDeleteOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=organizations/*/locations/*/operations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=organizations/*/locations/*/operations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseListOperations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=organizations/*/locations/*}/operations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseCmEnrollmentServiceRestTransport",) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/async_client.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/async_client.py index 73af4ce6db24..7db583592ea3 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/async_client.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/async_client.py @@ -295,10 +295,10 @@ async def list_frameworks( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListFrameworksAsyncPager: - r"""Lists all Frameworks (both Built-in and Custom) - available within a given parent resource. This method - supports pagination. The latest major version of each - Framework is returned. + r"""Lists the frameworks (both built-in and custom) that + are available within the parent resource. The latest + major version of each framework is returned. + This method supports pagination. .. code-block:: python @@ -329,12 +329,11 @@ async def sample_list_frameworks(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.ListFrameworksRequest, dict]]): - The request object. Request message for listing - Frameworks. + The request object. Request message for [ListFrameworks][]. parent (:class:`str`): Required. The parent resource name, in the format ``organizations/{organization}/locations/{location}``. - Only global location is supported. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -349,13 +348,11 @@ async def sample_list_frameworks(): Returns: google.cloud.cloudsecuritycompliance_v1.services.config.pagers.ListFrameworksAsyncPager: - Response message for listing - Frameworks. Contains a paginated list of - Framework resources. + The response message for [ListFrameworks][]. + Returns a paginated list of Framework resources. - Iterating over this object will yield - results and resolve additional pages - automatically. + Iterating over this object will yield results and + resolve additional pages automatically. """ # Create or coerce a protobuf request object. @@ -427,13 +424,11 @@ async def get_framework( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.Framework: - r"""Gets details of a single Framework. This method retrieves a - Framework resource, which can be either Built-in or Custom, - identified by its name. + r"""Gets details about a framework. This method retrieves the latest + major version of the framework. - By default, the latest major version of the Framework is - returned. A specific major version can be retrieved by - specifying the ``major_revision_id`` in the request. + To retrieve a specific major version, include + ``major_revision_id`` in the request. .. code-block:: python @@ -463,11 +458,12 @@ async def sample_get_framework(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.GetFrameworkRequest, dict]]): - The request object. Request message for getting a - Framework. + The request object. The request message for [GetFramework][]. name (:class:`str`): - Required. The name of the framework to retrieve. Format: - organizations/{organization}/locations/{location}/frameworks/{framework_id} + Required. The name of the framework to retrieve, in the + format + ``organizations/{organization}/locations/{location}/frameworks/{framework_id}`` + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -482,14 +478,11 @@ async def sample_get_framework(): Returns: google.cloud.cloudsecuritycompliance_v1.types.Framework: - A Framework is a collection of - CloudControls to address security and - compliance requirements. Frameworks can - be used for prevention, detection, and - auditing. They can be either built-in, - industry-standard frameworks provided by - GCP/AZURE/AWS (e.g., NIST, FedRAMP) or - custom frameworks created by users. + A framework is a collection of cloud + controls and regulatory controls that + represent security best practices or + industry-defined standards such as + FedRAMP or NIST. """ # Create or coerce a protobuf request object. @@ -552,9 +545,9 @@ async def create_framework( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.Framework: - r"""Creates a new Framework with type ``Custom`` under a given - parent resource. Frameworks with type ``Built-in`` are managed - by Google and cannot be created through this API. + r"""Creates a custom framework in a given parent + resource. You can't create built-in frameworks because + those are managed by Google. .. code-block:: python @@ -589,25 +582,25 @@ async def sample_create_framework(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.CreateFrameworkRequest, dict]]): - The request object. Request message for creating a - Framework + The request object. The request message for [CreateFramework][]. parent (:class:`str`): Required. The parent resource name, in the format ``organizations/{organization}/locations/{location}``. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. framework (:class:`google.cloud.cloudsecuritycompliance_v1.types.Framework`): - Required. The resource being created + Required. The resource being created. This corresponds to the ``framework`` field on the ``request`` instance; if ``request`` is provided, this should not be set. framework_id (:class:`str`): - Required. ID of the framework. - This is not the full name of the - framework. This is the last part of the - full name of the framework. + Required. The identifier (ID) of the + framework. The ID is not the full name + of the framework; it's the last part of + the full name of the framework. This corresponds to the ``framework_id`` field on the ``request`` instance; if ``request`` is provided, this @@ -622,14 +615,11 @@ async def sample_create_framework(): Returns: google.cloud.cloudsecuritycompliance_v1.types.Framework: - A Framework is a collection of - CloudControls to address security and - compliance requirements. Frameworks can - be used for prevention, detection, and - auditing. They can be either built-in, - industry-standard frameworks provided by - GCP/AZURE/AWS (e.g., NIST, FedRAMP) or - custom frameworks created by users. + A framework is a collection of cloud + controls and regulatory controls that + represent security best practices or + industry-defined standards such as + FedRAMP or NIST. """ # Create or coerce a protobuf request object. @@ -695,19 +685,18 @@ async def update_framework( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.Framework: - r"""Updates a single Framework. This method allows for partial - updates of a Framework resource. The fields to be updated are - specified using the ``update_mask``. + r"""Updates a custom framework. This method allows for partial + updates of a framework. Use the ``update_mask`` to specify which + fields to update. Consider the following: - - If an ``update_mask`` is provided, only the fields specified - in the mask will be updated. - - If no ``update_mask`` is provided, all fields present in the - request's ``framework`` body will be used to overwrite the - existing resource. + - If you provide an ``update_mask``, only the fields that are + specified in the mask are updated. + - If you don't provide an ``update_mask``, all the fields that + are present in the request's ``framework`` body are used to + overwrite the existing resource. - This operation can only be performed on Frameworks with type - ``CUSTOM``. A successful update will result in a new version of - the Framework. + You can only update frameworks with the ``CUSTOM`` type. A + successful update creates a new version of the framework. .. code-block:: python @@ -740,21 +729,22 @@ async def sample_update_framework(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.UpdateFrameworkRequest, dict]]): - The request object. Request message for updating a - Framework. + The request object. The request message for [UpdateFramework][]. framework (:class:`google.cloud.cloudsecuritycompliance_v1.types.Framework`): - Required. The resource being updated + Required. The resource that is being + updated. + This corresponds to the ``framework`` field on the ``request`` instance; if ``request`` is provided, this should not be set. update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): - Optional. Field mask is used to specify the fields to be - overwritten in the Framework resource by the update. The - fields specified in the update_mask are relative to the - resource, not the full request. A field will be - overwritten if it is in the mask. If the user does not - provide a mask then all fields present in the request - will be overwritten. + Optional. A field mask is used to specify the fields to + be overwritten in the framework resource by the update. + The fields specified in the ``update_mask`` are relative + to the resource, not the full request. A field is + overwritten if it is in the mask. If you don't provide a + mask then all fields present in the request will be + overwritten. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -769,14 +759,11 @@ async def sample_update_framework(): Returns: google.cloud.cloudsecuritycompliance_v1.types.Framework: - A Framework is a collection of - CloudControls to address security and - compliance requirements. Frameworks can - be used for prevention, detection, and - auditing. They can be either built-in, - industry-standard frameworks provided by - GCP/AZURE/AWS (e.g., NIST, FedRAMP) or - custom frameworks created by users. + A framework is a collection of cloud + controls and regulatory controls that + represent security best practices or + industry-defined standards such as + FedRAMP or NIST. """ # Create or coerce a protobuf request object. @@ -841,14 +828,14 @@ async def delete_framework( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: - r"""Deletes a single Custom Framework, including all its minor and - minor revisions. + r"""Deletes a custom framework, including all its major and minor + revisions. Consider the following: - - This operation can only be performed on Frameworks with type - ``CUSTOM``. Built-in Frameworks cannot be deleted. - - The Framework cannot be deleted if it is currently deployed on - any resource. - - This action is permanent and cannot be undone. + - You can't delete built-in frameworks. You can only delete + frameworks with type ``CUSTOM``. + - You can't delete frameworks that are deployed to a resource. + - You can't restore a deleted framework. This action is + permanent. .. code-block:: python @@ -875,11 +862,11 @@ async def sample_delete_framework(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.DeleteFrameworkRequest, dict]]): - The request object. Request message for deleting a - Framework. + The request object. Request message for [DeleteFramework][]. name (:class:`str`): - Required. Name of the resource, in the format + Required. The name of the resource, in the format ``organizations/{organization}/locations/{location}/frameworks/{framework}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -947,10 +934,10 @@ async def list_cloud_controls( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListCloudControlsAsyncPager: - r"""Lists all CloudControls (both Built-in and Custom) - available within a given parent resource. This method - supports pagination. The latest major version of each - CloudControl is returned. + r"""Lists the cloud controls (both built-in and custom) + that are available in a given parent resource. The + latest major version of each cloud control is returned. + This method supports pagination. .. code-block:: python @@ -981,11 +968,11 @@ async def sample_list_cloud_controls(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.ListCloudControlsRequest, dict]]): - The request object. Request message for listing - CloudControls. + The request object. Request message for [ListCloudControls][]. parent (:class:`str`): Required. The parent resource name, in the format ``organizations/{organization}/locations/{location}``. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -1000,11 +987,10 @@ async def sample_list_cloud_controls(): Returns: google.cloud.cloudsecuritycompliance_v1.services.config.pagers.ListCloudControlsAsyncPager: - Response message for - ListCloudControls. - Iterating over this object will yield - results and resolve additional pages - automatically. + The response message for [ListCloudControls][]. + + Iterating over this object will yield results and + resolve additional pages automatically. """ # Create or coerce a protobuf request object. @@ -1076,13 +1062,13 @@ async def get_cloud_control( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.CloudControl: - r"""Gets details of a single CloudControl. This method retrieves a - CloudControl resource, which can be either Built-in or Custom, - identified by its name. + r"""Gets details about a cloud control. This method retrieves the + latest major version of a cloud control that you identify by + name. - By default, the latest major version of the CloudControl is - returned. A specific major version can be retrieved by - specifying the ``major_revision_id`` in the request. + By default, the latest major version of the cloud control is + returned. To retrieve a specific major version, include + ``major_revision_id`` in the request. .. code-block:: python @@ -1112,12 +1098,12 @@ async def sample_get_cloud_control(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.GetCloudControlRequest, dict]]): - The request object. Request message for getting a - CloudControl. + The request object. The request message for [GetCloudControl][]. name (:class:`str`): - Required. The name of the cloudcontrol to retrieve in - the format: - organizations/{organization}/locations/{location}/cloudControls/{cloud_control} + Required. The name of the cloud control to retrieve, in + the format + ``organizations/{organization}/locations/{location}/cloudControls/{cloud_control}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1132,14 +1118,10 @@ async def sample_get_cloud_control(): Returns: google.cloud.cloudsecuritycompliance_v1.types.CloudControl: - A CloudControl is the fundamental unit encapsulating the rules - to meet a specific security or compliance intent. It - can contain various rule types (like Organization - Policies, CEL expressions, etc.) enabling different - enforcement modes (Preventive, Detective, Audit). - CloudControls are often parameterized for reusability - and can be either BUILT_IN (provided by Google) or - CUSTOM (defined by the user). + A cloud control is a set of rules and + associated metadata that you can use to + define your organization's security or + compliance intent. """ # Create or coerce a protobuf request object. @@ -1202,9 +1184,10 @@ async def create_cloud_control( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.CloudControl: - r"""Creates a new CloudControl with type ``Custom`` under a given - parent resource. ``Built-in`` CloudControls are managed by - Google and cannot be created through this API. + r"""Creates a custom cloud control in a given parent + resource. + You can't create built-in cloud controls because those + are managed by Google. .. code-block:: python @@ -1239,24 +1222,26 @@ async def sample_create_cloud_control(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.CreateCloudControlRequest, dict]]): - The request object. Request message for creating a - CloudControl + The request object. The request message for [CreateCloudControl][]. parent (:class:`str`): Required. The parent resource name, in the format ``organizations/{organization}/locations/{location}``. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. cloud_control (:class:`google.cloud.cloudsecuritycompliance_v1.types.CloudControl`): - Required. The resource being created + Required. The cloud control that's + being created. + This corresponds to the ``cloud_control`` field on the ``request`` instance; if ``request`` is provided, this should not be set. cloud_control_id (:class:`str`): - Required. ID of the CloudControl. This is the last - segment of the CloudControl resource name. Format: - ``^[a-zA-Z][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$``. + Required. The identifier for the cloud control, which is + the last segment of the cloud control name. The format + is ``^[a-zA-Z][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$``. This corresponds to the ``cloud_control_id`` field on the ``request`` instance; if ``request`` is provided, this @@ -1271,14 +1256,10 @@ async def sample_create_cloud_control(): Returns: google.cloud.cloudsecuritycompliance_v1.types.CloudControl: - A CloudControl is the fundamental unit encapsulating the rules - to meet a specific security or compliance intent. It - can contain various rule types (like Organization - Policies, CEL expressions, etc.) enabling different - enforcement modes (Preventive, Detective, Audit). - CloudControls are often parameterized for reusability - and can be either BUILT_IN (provided by Google) or - CUSTOM (defined by the user). + A cloud control is a set of rules and + associated metadata that you can use to + define your organization's security or + compliance intent. """ # Create or coerce a protobuf request object. @@ -1344,18 +1325,18 @@ async def update_cloud_control( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.CloudControl: - r"""Updates a single CloudControl. This method allows for partial - updates of a Custom CloudControl resource. Built-in - CloudControls cannot be updated. + r"""Updates a custom cloud control. This method allows for partial + updates of a cloud control. Use the ``update_mask`` to specify + which fields to update. Consider the following: - - If an ``update_mask`` is provided, only the fields specified - in the mask will be updated. - - If no ``update_mask`` is provided, all fields present in the - request's ``cloud_control`` body will be used to overwrite the - existing resource. + - If you provide an ``update_mask``, only the fields that are + specified in the mask are updated. + - If you don't provide an ``update_mask``, all the fields that + are present in the request's ``cloud_control`` body are used + to overwrite the existing resource. - A successful update will result in a new version of the - CloudControl. + You can only update cloud controls with the ``CUSTOM`` type. A + successful update creates a new version of the cloud control. .. code-block:: python @@ -1388,27 +1369,29 @@ async def sample_update_cloud_control(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.UpdateCloudControlRequest, dict]]): - The request object. Request message for - UpdateCloudControl. + The request object. The request message for [UpdateCloudControl][]. cloud_control (:class:`google.cloud.cloudsecuritycompliance_v1.types.CloudControl`): - Required. The resource being updated + Required. The cloud control that + you're updating. + This corresponds to the ``cloud_control`` field on the ``request`` instance; if ``request`` is provided, this should not be set. update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): - Optional. Field mask is used to specify the fields to be - overwritten in the CloudControl resource by the update. - The fields specified in the update_mask are relative to - the resource, not the full request. A field will be - overwritten if it is in the mask. If the user does not - provide a mask then all fields present in the request - will be overwritten. The fields that can be updated are: - - 1. Display_name - 2. Description - 3. Parameters - 4. Rules - 5. ParameterSpec. + Optional. Use a field mask to specify the fields to be + overwritten in the cloud control during the update. The + fields that you specify in the ``update_mask`` are + relative to the cloud control, not the full request. A + field is overwritten if it is in the mask. If you don't + provide a mask, all fields in the request are updated. + + You can update the following fields: + + - Display name + - Description + - Parameters + - Rules + - Parameter specification This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -1423,14 +1406,10 @@ async def sample_update_cloud_control(): Returns: google.cloud.cloudsecuritycompliance_v1.types.CloudControl: - A CloudControl is the fundamental unit encapsulating the rules - to meet a specific security or compliance intent. It - can contain various rule types (like Organization - Policies, CEL expressions, etc.) enabling different - enforcement modes (Preventive, Detective, Audit). - CloudControls are often parameterized for reusability - and can be either BUILT_IN (provided by Google) or - CUSTOM (defined by the user). + A cloud control is a set of rules and + associated metadata that you can use to + define your organization's security or + compliance intent. """ # Create or coerce a protobuf request object. @@ -1495,14 +1474,15 @@ async def delete_cloud_control( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: - r"""Deletes a single Custom CloudControl, including all its major - and minor revisions. + r"""Deletes a custom cloud control, including all its major and + minor revisions. Consider the following: - - This operation can only be performed on CloudControls with - type ``CUSTOM``. Built-in CloudControls cannot be deleted. - - The CloudControl cannot be deleted if any of its revisions are - currently referenced by any Framework. - - This action is permanent and cannot be undone. + - You can't delete built-in cloud controls. You can only delete + cloud controls with type ``CUSTOM``. + - You can't delete cloud controls if any of the versions are + referenced by a framework. + - You can't restore a deleted cloud control. This action is + permanent. .. code-block:: python @@ -1529,11 +1509,12 @@ async def sample_delete_cloud_control(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.DeleteCloudControlRequest, dict]]): - The request object. Request message for deleting a - CloudControl. + The request object. The request message for [DeleteCloudControl][]. name (:class:`str`): - Required. Name of the resource, in the format + Required. The name of the cloud control to delete, in + the format ``organizations/{organization}/locations/{location}/CloudControls/{CloudControl}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/client.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/client.py index 2da50f733616..9971ee457f61 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/client.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/client.py @@ -743,10 +743,10 @@ def list_frameworks( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListFrameworksPager: - r"""Lists all Frameworks (both Built-in and Custom) - available within a given parent resource. This method - supports pagination. The latest major version of each - Framework is returned. + r"""Lists the frameworks (both built-in and custom) that + are available within the parent resource. The latest + major version of each framework is returned. + This method supports pagination. .. code-block:: python @@ -777,12 +777,11 @@ def sample_list_frameworks(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.ListFrameworksRequest, dict]): - The request object. Request message for listing - Frameworks. + The request object. Request message for [ListFrameworks][]. parent (str): Required. The parent resource name, in the format ``organizations/{organization}/locations/{location}``. - Only global location is supported. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -797,13 +796,11 @@ def sample_list_frameworks(): Returns: google.cloud.cloudsecuritycompliance_v1.services.config.pagers.ListFrameworksPager: - Response message for listing - Frameworks. Contains a paginated list of - Framework resources. + The response message for [ListFrameworks][]. + Returns a paginated list of Framework resources. - Iterating over this object will yield - results and resolve additional pages - automatically. + Iterating over this object will yield results and + resolve additional pages automatically. """ # Create or coerce a protobuf request object. @@ -872,13 +869,11 @@ def get_framework( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.Framework: - r"""Gets details of a single Framework. This method retrieves a - Framework resource, which can be either Built-in or Custom, - identified by its name. + r"""Gets details about a framework. This method retrieves the latest + major version of the framework. - By default, the latest major version of the Framework is - returned. A specific major version can be retrieved by - specifying the ``major_revision_id`` in the request. + To retrieve a specific major version, include + ``major_revision_id`` in the request. .. code-block:: python @@ -908,11 +903,12 @@ def sample_get_framework(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.GetFrameworkRequest, dict]): - The request object. Request message for getting a - Framework. + The request object. The request message for [GetFramework][]. name (str): - Required. The name of the framework to retrieve. Format: - organizations/{organization}/locations/{location}/frameworks/{framework_id} + Required. The name of the framework to retrieve, in the + format + ``organizations/{organization}/locations/{location}/frameworks/{framework_id}`` + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -927,14 +923,11 @@ def sample_get_framework(): Returns: google.cloud.cloudsecuritycompliance_v1.types.Framework: - A Framework is a collection of - CloudControls to address security and - compliance requirements. Frameworks can - be used for prevention, detection, and - auditing. They can be either built-in, - industry-standard frameworks provided by - GCP/AZURE/AWS (e.g., NIST, FedRAMP) or - custom frameworks created by users. + A framework is a collection of cloud + controls and regulatory controls that + represent security best practices or + industry-defined standards such as + FedRAMP or NIST. """ # Create or coerce a protobuf request object. @@ -994,9 +987,9 @@ def create_framework( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.Framework: - r"""Creates a new Framework with type ``Custom`` under a given - parent resource. Frameworks with type ``Built-in`` are managed - by Google and cannot be created through this API. + r"""Creates a custom framework in a given parent + resource. You can't create built-in frameworks because + those are managed by Google. .. code-block:: python @@ -1031,25 +1024,25 @@ def sample_create_framework(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.CreateFrameworkRequest, dict]): - The request object. Request message for creating a - Framework + The request object. The request message for [CreateFramework][]. parent (str): Required. The parent resource name, in the format ``organizations/{organization}/locations/{location}``. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. framework (google.cloud.cloudsecuritycompliance_v1.types.Framework): - Required. The resource being created + Required. The resource being created. This corresponds to the ``framework`` field on the ``request`` instance; if ``request`` is provided, this should not be set. framework_id (str): - Required. ID of the framework. - This is not the full name of the - framework. This is the last part of the - full name of the framework. + Required. The identifier (ID) of the + framework. The ID is not the full name + of the framework; it's the last part of + the full name of the framework. This corresponds to the ``framework_id`` field on the ``request`` instance; if ``request`` is provided, this @@ -1064,14 +1057,11 @@ def sample_create_framework(): Returns: google.cloud.cloudsecuritycompliance_v1.types.Framework: - A Framework is a collection of - CloudControls to address security and - compliance requirements. Frameworks can - be used for prevention, detection, and - auditing. They can be either built-in, - industry-standard frameworks provided by - GCP/AZURE/AWS (e.g., NIST, FedRAMP) or - custom frameworks created by users. + A framework is a collection of cloud + controls and regulatory controls that + represent security best practices or + industry-defined standards such as + FedRAMP or NIST. """ # Create or coerce a protobuf request object. @@ -1134,19 +1124,18 @@ def update_framework( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.Framework: - r"""Updates a single Framework. This method allows for partial - updates of a Framework resource. The fields to be updated are - specified using the ``update_mask``. + r"""Updates a custom framework. This method allows for partial + updates of a framework. Use the ``update_mask`` to specify which + fields to update. Consider the following: - - If an ``update_mask`` is provided, only the fields specified - in the mask will be updated. - - If no ``update_mask`` is provided, all fields present in the - request's ``framework`` body will be used to overwrite the - existing resource. + - If you provide an ``update_mask``, only the fields that are + specified in the mask are updated. + - If you don't provide an ``update_mask``, all the fields that + are present in the request's ``framework`` body are used to + overwrite the existing resource. - This operation can only be performed on Frameworks with type - ``CUSTOM``. A successful update will result in a new version of - the Framework. + You can only update frameworks with the ``CUSTOM`` type. A + successful update creates a new version of the framework. .. code-block:: python @@ -1179,21 +1168,22 @@ def sample_update_framework(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.UpdateFrameworkRequest, dict]): - The request object. Request message for updating a - Framework. + The request object. The request message for [UpdateFramework][]. framework (google.cloud.cloudsecuritycompliance_v1.types.Framework): - Required. The resource being updated + Required. The resource that is being + updated. + This corresponds to the ``framework`` field on the ``request`` instance; if ``request`` is provided, this should not be set. update_mask (google.protobuf.field_mask_pb2.FieldMask): - Optional. Field mask is used to specify the fields to be - overwritten in the Framework resource by the update. The - fields specified in the update_mask are relative to the - resource, not the full request. A field will be - overwritten if it is in the mask. If the user does not - provide a mask then all fields present in the request - will be overwritten. + Optional. A field mask is used to specify the fields to + be overwritten in the framework resource by the update. + The fields specified in the ``update_mask`` are relative + to the resource, not the full request. A field is + overwritten if it is in the mask. If you don't provide a + mask then all fields present in the request will be + overwritten. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -1208,14 +1198,11 @@ def sample_update_framework(): Returns: google.cloud.cloudsecuritycompliance_v1.types.Framework: - A Framework is a collection of - CloudControls to address security and - compliance requirements. Frameworks can - be used for prevention, detection, and - auditing. They can be either built-in, - industry-standard frameworks provided by - GCP/AZURE/AWS (e.g., NIST, FedRAMP) or - custom frameworks created by users. + A framework is a collection of cloud + controls and regulatory controls that + represent security best practices or + industry-defined standards such as + FedRAMP or NIST. """ # Create or coerce a protobuf request object. @@ -1277,14 +1264,14 @@ def delete_framework( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: - r"""Deletes a single Custom Framework, including all its minor and - minor revisions. + r"""Deletes a custom framework, including all its major and minor + revisions. Consider the following: - - This operation can only be performed on Frameworks with type - ``CUSTOM``. Built-in Frameworks cannot be deleted. - - The Framework cannot be deleted if it is currently deployed on - any resource. - - This action is permanent and cannot be undone. + - You can't delete built-in frameworks. You can only delete + frameworks with type ``CUSTOM``. + - You can't delete frameworks that are deployed to a resource. + - You can't restore a deleted framework. This action is + permanent. .. code-block:: python @@ -1311,11 +1298,11 @@ def sample_delete_framework(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.DeleteFrameworkRequest, dict]): - The request object. Request message for deleting a - Framework. + The request object. Request message for [DeleteFramework][]. name (str): - Required. Name of the resource, in the format + Required. The name of the resource, in the format ``organizations/{organization}/locations/{location}/frameworks/{framework}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1380,10 +1367,10 @@ def list_cloud_controls( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListCloudControlsPager: - r"""Lists all CloudControls (both Built-in and Custom) - available within a given parent resource. This method - supports pagination. The latest major version of each - CloudControl is returned. + r"""Lists the cloud controls (both built-in and custom) + that are available in a given parent resource. The + latest major version of each cloud control is returned. + This method supports pagination. .. code-block:: python @@ -1414,11 +1401,11 @@ def sample_list_cloud_controls(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.ListCloudControlsRequest, dict]): - The request object. Request message for listing - CloudControls. + The request object. Request message for [ListCloudControls][]. parent (str): Required. The parent resource name, in the format ``organizations/{organization}/locations/{location}``. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -1433,11 +1420,10 @@ def sample_list_cloud_controls(): Returns: google.cloud.cloudsecuritycompliance_v1.services.config.pagers.ListCloudControlsPager: - Response message for - ListCloudControls. - Iterating over this object will yield - results and resolve additional pages - automatically. + The response message for [ListCloudControls][]. + + Iterating over this object will yield results and + resolve additional pages automatically. """ # Create or coerce a protobuf request object. @@ -1506,13 +1492,13 @@ def get_cloud_control( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.CloudControl: - r"""Gets details of a single CloudControl. This method retrieves a - CloudControl resource, which can be either Built-in or Custom, - identified by its name. + r"""Gets details about a cloud control. This method retrieves the + latest major version of a cloud control that you identify by + name. - By default, the latest major version of the CloudControl is - returned. A specific major version can be retrieved by - specifying the ``major_revision_id`` in the request. + By default, the latest major version of the cloud control is + returned. To retrieve a specific major version, include + ``major_revision_id`` in the request. .. code-block:: python @@ -1542,12 +1528,12 @@ def sample_get_cloud_control(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.GetCloudControlRequest, dict]): - The request object. Request message for getting a - CloudControl. + The request object. The request message for [GetCloudControl][]. name (str): - Required. The name of the cloudcontrol to retrieve in - the format: - organizations/{organization}/locations/{location}/cloudControls/{cloud_control} + Required. The name of the cloud control to retrieve, in + the format + ``organizations/{organization}/locations/{location}/cloudControls/{cloud_control}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1562,14 +1548,10 @@ def sample_get_cloud_control(): Returns: google.cloud.cloudsecuritycompliance_v1.types.CloudControl: - A CloudControl is the fundamental unit encapsulating the rules - to meet a specific security or compliance intent. It - can contain various rule types (like Organization - Policies, CEL expressions, etc.) enabling different - enforcement modes (Preventive, Detective, Audit). - CloudControls are often parameterized for reusability - and can be either BUILT_IN (provided by Google) or - CUSTOM (defined by the user). + A cloud control is a set of rules and + associated metadata that you can use to + define your organization's security or + compliance intent. """ # Create or coerce a protobuf request object. @@ -1629,9 +1611,10 @@ def create_cloud_control( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.CloudControl: - r"""Creates a new CloudControl with type ``Custom`` under a given - parent resource. ``Built-in`` CloudControls are managed by - Google and cannot be created through this API. + r"""Creates a custom cloud control in a given parent + resource. + You can't create built-in cloud controls because those + are managed by Google. .. code-block:: python @@ -1666,24 +1649,26 @@ def sample_create_cloud_control(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.CreateCloudControlRequest, dict]): - The request object. Request message for creating a - CloudControl + The request object. The request message for [CreateCloudControl][]. parent (str): Required. The parent resource name, in the format ``organizations/{organization}/locations/{location}``. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. cloud_control (google.cloud.cloudsecuritycompliance_v1.types.CloudControl): - Required. The resource being created + Required. The cloud control that's + being created. + This corresponds to the ``cloud_control`` field on the ``request`` instance; if ``request`` is provided, this should not be set. cloud_control_id (str): - Required. ID of the CloudControl. This is the last - segment of the CloudControl resource name. Format: - ``^[a-zA-Z][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$``. + Required. The identifier for the cloud control, which is + the last segment of the cloud control name. The format + is ``^[a-zA-Z][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$``. This corresponds to the ``cloud_control_id`` field on the ``request`` instance; if ``request`` is provided, this @@ -1698,14 +1683,10 @@ def sample_create_cloud_control(): Returns: google.cloud.cloudsecuritycompliance_v1.types.CloudControl: - A CloudControl is the fundamental unit encapsulating the rules - to meet a specific security or compliance intent. It - can contain various rule types (like Organization - Policies, CEL expressions, etc.) enabling different - enforcement modes (Preventive, Detective, Audit). - CloudControls are often parameterized for reusability - and can be either BUILT_IN (provided by Google) or - CUSTOM (defined by the user). + A cloud control is a set of rules and + associated metadata that you can use to + define your organization's security or + compliance intent. """ # Create or coerce a protobuf request object. @@ -1768,18 +1749,18 @@ def update_cloud_control( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> common.CloudControl: - r"""Updates a single CloudControl. This method allows for partial - updates of a Custom CloudControl resource. Built-in - CloudControls cannot be updated. + r"""Updates a custom cloud control. This method allows for partial + updates of a cloud control. Use the ``update_mask`` to specify + which fields to update. Consider the following: - - If an ``update_mask`` is provided, only the fields specified - in the mask will be updated. - - If no ``update_mask`` is provided, all fields present in the - request's ``cloud_control`` body will be used to overwrite the - existing resource. + - If you provide an ``update_mask``, only the fields that are + specified in the mask are updated. + - If you don't provide an ``update_mask``, all the fields that + are present in the request's ``cloud_control`` body are used + to overwrite the existing resource. - A successful update will result in a new version of the - CloudControl. + You can only update cloud controls with the ``CUSTOM`` type. A + successful update creates a new version of the cloud control. .. code-block:: python @@ -1812,27 +1793,29 @@ def sample_update_cloud_control(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.UpdateCloudControlRequest, dict]): - The request object. Request message for - UpdateCloudControl. + The request object. The request message for [UpdateCloudControl][]. cloud_control (google.cloud.cloudsecuritycompliance_v1.types.CloudControl): - Required. The resource being updated + Required. The cloud control that + you're updating. + This corresponds to the ``cloud_control`` field on the ``request`` instance; if ``request`` is provided, this should not be set. update_mask (google.protobuf.field_mask_pb2.FieldMask): - Optional. Field mask is used to specify the fields to be - overwritten in the CloudControl resource by the update. - The fields specified in the update_mask are relative to - the resource, not the full request. A field will be - overwritten if it is in the mask. If the user does not - provide a mask then all fields present in the request - will be overwritten. The fields that can be updated are: - - 1. Display_name - 2. Description - 3. Parameters - 4. Rules - 5. ParameterSpec. + Optional. Use a field mask to specify the fields to be + overwritten in the cloud control during the update. The + fields that you specify in the ``update_mask`` are + relative to the cloud control, not the full request. A + field is overwritten if it is in the mask. If you don't + provide a mask, all fields in the request are updated. + + You can update the following fields: + + - Display name + - Description + - Parameters + - Rules + - Parameter specification This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -1847,14 +1830,10 @@ def sample_update_cloud_control(): Returns: google.cloud.cloudsecuritycompliance_v1.types.CloudControl: - A CloudControl is the fundamental unit encapsulating the rules - to meet a specific security or compliance intent. It - can contain various rule types (like Organization - Policies, CEL expressions, etc.) enabling different - enforcement modes (Preventive, Detective, Audit). - CloudControls are often parameterized for reusability - and can be either BUILT_IN (provided by Google) or - CUSTOM (defined by the user). + A cloud control is a set of rules and + associated metadata that you can use to + define your organization's security or + compliance intent. """ # Create or coerce a protobuf request object. @@ -1916,14 +1895,15 @@ def delete_cloud_control( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> None: - r"""Deletes a single Custom CloudControl, including all its major - and minor revisions. + r"""Deletes a custom cloud control, including all its major and + minor revisions. Consider the following: - - This operation can only be performed on CloudControls with - type ``CUSTOM``. Built-in CloudControls cannot be deleted. - - The CloudControl cannot be deleted if any of its revisions are - currently referenced by any Framework. - - This action is permanent and cannot be undone. + - You can't delete built-in cloud controls. You can only delete + cloud controls with type ``CUSTOM``. + - You can't delete cloud controls if any of the versions are + referenced by a framework. + - You can't restore a deleted cloud control. This action is + permanent. .. code-block:: python @@ -1950,11 +1930,12 @@ def sample_delete_cloud_control(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.DeleteCloudControlRequest, dict]): - The request object. Request message for deleting a - CloudControl. + The request object. The request message for [DeleteCloudControl][]. name (str): - Required. Name of the resource, in the format + Required. The name of the cloud control to delete, in + the format ``organizations/{organization}/locations/{location}/CloudControls/{CloudControl}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/grpc.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/grpc.py index d46ad7039a63..7978591db5cd 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/grpc.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/grpc.py @@ -331,10 +331,10 @@ def list_frameworks( ) -> Callable[[config.ListFrameworksRequest], config.ListFrameworksResponse]: r"""Return a callable for the list frameworks method over gRPC. - Lists all Frameworks (both Built-in and Custom) - available within a given parent resource. This method - supports pagination. The latest major version of each - Framework is returned. + Lists the frameworks (both built-in and custom) that + are available within the parent resource. The latest + major version of each framework is returned. + This method supports pagination. Returns: Callable[[~.ListFrameworksRequest], @@ -358,13 +358,11 @@ def list_frameworks( def get_framework(self) -> Callable[[config.GetFrameworkRequest], common.Framework]: r"""Return a callable for the get framework method over gRPC. - Gets details of a single Framework. This method retrieves a - Framework resource, which can be either Built-in or Custom, - identified by its name. + Gets details about a framework. This method retrieves the latest + major version of the framework. - By default, the latest major version of the Framework is - returned. A specific major version can be retrieved by - specifying the ``major_revision_id`` in the request. + To retrieve a specific major version, include + ``major_revision_id`` in the request. Returns: Callable[[~.GetFrameworkRequest], @@ -390,9 +388,9 @@ def create_framework( ) -> Callable[[config.CreateFrameworkRequest], common.Framework]: r"""Return a callable for the create framework method over gRPC. - Creates a new Framework with type ``Custom`` under a given - parent resource. Frameworks with type ``Built-in`` are managed - by Google and cannot be created through this API. + Creates a custom framework in a given parent + resource. You can't create built-in frameworks because + those are managed by Google. Returns: Callable[[~.CreateFrameworkRequest], @@ -418,19 +416,18 @@ def update_framework( ) -> Callable[[config.UpdateFrameworkRequest], common.Framework]: r"""Return a callable for the update framework method over gRPC. - Updates a single Framework. This method allows for partial - updates of a Framework resource. The fields to be updated are - specified using the ``update_mask``. + Updates a custom framework. This method allows for partial + updates of a framework. Use the ``update_mask`` to specify which + fields to update. Consider the following: - - If an ``update_mask`` is provided, only the fields specified - in the mask will be updated. - - If no ``update_mask`` is provided, all fields present in the - request's ``framework`` body will be used to overwrite the - existing resource. + - If you provide an ``update_mask``, only the fields that are + specified in the mask are updated. + - If you don't provide an ``update_mask``, all the fields that + are present in the request's ``framework`` body are used to + overwrite the existing resource. - This operation can only be performed on Frameworks with type - ``CUSTOM``. A successful update will result in a new version of - the Framework. + You can only update frameworks with the ``CUSTOM`` type. A + successful update creates a new version of the framework. Returns: Callable[[~.UpdateFrameworkRequest], @@ -456,14 +453,14 @@ def delete_framework( ) -> Callable[[config.DeleteFrameworkRequest], empty_pb2.Empty]: r"""Return a callable for the delete framework method over gRPC. - Deletes a single Custom Framework, including all its minor and - minor revisions. + Deletes a custom framework, including all its major and minor + revisions. Consider the following: - - This operation can only be performed on Frameworks with type - ``CUSTOM``. Built-in Frameworks cannot be deleted. - - The Framework cannot be deleted if it is currently deployed on - any resource. - - This action is permanent and cannot be undone. + - You can't delete built-in frameworks. You can only delete + frameworks with type ``CUSTOM``. + - You can't delete frameworks that are deployed to a resource. + - You can't restore a deleted framework. This action is + permanent. Returns: Callable[[~.DeleteFrameworkRequest], @@ -489,10 +486,10 @@ def list_cloud_controls( ) -> Callable[[config.ListCloudControlsRequest], config.ListCloudControlsResponse]: r"""Return a callable for the list cloud controls method over gRPC. - Lists all CloudControls (both Built-in and Custom) - available within a given parent resource. This method - supports pagination. The latest major version of each - CloudControl is returned. + Lists the cloud controls (both built-in and custom) + that are available in a given parent resource. The + latest major version of each cloud control is returned. + This method supports pagination. Returns: Callable[[~.ListCloudControlsRequest], @@ -518,13 +515,13 @@ def get_cloud_control( ) -> Callable[[config.GetCloudControlRequest], common.CloudControl]: r"""Return a callable for the get cloud control method over gRPC. - Gets details of a single CloudControl. This method retrieves a - CloudControl resource, which can be either Built-in or Custom, - identified by its name. + Gets details about a cloud control. This method retrieves the + latest major version of a cloud control that you identify by + name. - By default, the latest major version of the CloudControl is - returned. A specific major version can be retrieved by - specifying the ``major_revision_id`` in the request. + By default, the latest major version of the cloud control is + returned. To retrieve a specific major version, include + ``major_revision_id`` in the request. Returns: Callable[[~.GetCloudControlRequest], @@ -550,9 +547,10 @@ def create_cloud_control( ) -> Callable[[config.CreateCloudControlRequest], common.CloudControl]: r"""Return a callable for the create cloud control method over gRPC. - Creates a new CloudControl with type ``Custom`` under a given - parent resource. ``Built-in`` CloudControls are managed by - Google and cannot be created through this API. + Creates a custom cloud control in a given parent + resource. + You can't create built-in cloud controls because those + are managed by Google. Returns: Callable[[~.CreateCloudControlRequest], @@ -578,18 +576,18 @@ def update_cloud_control( ) -> Callable[[config.UpdateCloudControlRequest], common.CloudControl]: r"""Return a callable for the update cloud control method over gRPC. - Updates a single CloudControl. This method allows for partial - updates of a Custom CloudControl resource. Built-in - CloudControls cannot be updated. + Updates a custom cloud control. This method allows for partial + updates of a cloud control. Use the ``update_mask`` to specify + which fields to update. Consider the following: - - If an ``update_mask`` is provided, only the fields specified - in the mask will be updated. - - If no ``update_mask`` is provided, all fields present in the - request's ``cloud_control`` body will be used to overwrite the - existing resource. + - If you provide an ``update_mask``, only the fields that are + specified in the mask are updated. + - If you don't provide an ``update_mask``, all the fields that + are present in the request's ``cloud_control`` body are used + to overwrite the existing resource. - A successful update will result in a new version of the - CloudControl. + You can only update cloud controls with the ``CUSTOM`` type. A + successful update creates a new version of the cloud control. Returns: Callable[[~.UpdateCloudControlRequest], @@ -615,14 +613,15 @@ def delete_cloud_control( ) -> Callable[[config.DeleteCloudControlRequest], empty_pb2.Empty]: r"""Return a callable for the delete cloud control method over gRPC. - Deletes a single Custom CloudControl, including all its major - and minor revisions. + Deletes a custom cloud control, including all its major and + minor revisions. Consider the following: - - This operation can only be performed on CloudControls with - type ``CUSTOM``. Built-in CloudControls cannot be deleted. - - The CloudControl cannot be deleted if any of its revisions are - currently referenced by any Framework. - - This action is permanent and cannot be undone. + - You can't delete built-in cloud controls. You can only delete + cloud controls with type ``CUSTOM``. + - You can't delete cloud controls if any of the versions are + referenced by a framework. + - You can't restore a deleted cloud control. This action is + permanent. Returns: Callable[[~.DeleteCloudControlRequest], diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/grpc_asyncio.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/grpc_asyncio.py index 120f786fde4d..09ed665d2c8d 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/grpc_asyncio.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/grpc_asyncio.py @@ -341,10 +341,10 @@ def list_frameworks( ]: r"""Return a callable for the list frameworks method over gRPC. - Lists all Frameworks (both Built-in and Custom) - available within a given parent resource. This method - supports pagination. The latest major version of each - Framework is returned. + Lists the frameworks (both built-in and custom) that + are available within the parent resource. The latest + major version of each framework is returned. + This method supports pagination. Returns: Callable[[~.ListFrameworksRequest], @@ -370,13 +370,11 @@ def get_framework( ) -> Callable[[config.GetFrameworkRequest], Awaitable[common.Framework]]: r"""Return a callable for the get framework method over gRPC. - Gets details of a single Framework. This method retrieves a - Framework resource, which can be either Built-in or Custom, - identified by its name. + Gets details about a framework. This method retrieves the latest + major version of the framework. - By default, the latest major version of the Framework is - returned. A specific major version can be retrieved by - specifying the ``major_revision_id`` in the request. + To retrieve a specific major version, include + ``major_revision_id`` in the request. Returns: Callable[[~.GetFrameworkRequest], @@ -402,9 +400,9 @@ def create_framework( ) -> Callable[[config.CreateFrameworkRequest], Awaitable[common.Framework]]: r"""Return a callable for the create framework method over gRPC. - Creates a new Framework with type ``Custom`` under a given - parent resource. Frameworks with type ``Built-in`` are managed - by Google and cannot be created through this API. + Creates a custom framework in a given parent + resource. You can't create built-in frameworks because + those are managed by Google. Returns: Callable[[~.CreateFrameworkRequest], @@ -430,19 +428,18 @@ def update_framework( ) -> Callable[[config.UpdateFrameworkRequest], Awaitable[common.Framework]]: r"""Return a callable for the update framework method over gRPC. - Updates a single Framework. This method allows for partial - updates of a Framework resource. The fields to be updated are - specified using the ``update_mask``. + Updates a custom framework. This method allows for partial + updates of a framework. Use the ``update_mask`` to specify which + fields to update. Consider the following: - - If an ``update_mask`` is provided, only the fields specified - in the mask will be updated. - - If no ``update_mask`` is provided, all fields present in the - request's ``framework`` body will be used to overwrite the - existing resource. + - If you provide an ``update_mask``, only the fields that are + specified in the mask are updated. + - If you don't provide an ``update_mask``, all the fields that + are present in the request's ``framework`` body are used to + overwrite the existing resource. - This operation can only be performed on Frameworks with type - ``CUSTOM``. A successful update will result in a new version of - the Framework. + You can only update frameworks with the ``CUSTOM`` type. A + successful update creates a new version of the framework. Returns: Callable[[~.UpdateFrameworkRequest], @@ -468,14 +465,14 @@ def delete_framework( ) -> Callable[[config.DeleteFrameworkRequest], Awaitable[empty_pb2.Empty]]: r"""Return a callable for the delete framework method over gRPC. - Deletes a single Custom Framework, including all its minor and - minor revisions. + Deletes a custom framework, including all its major and minor + revisions. Consider the following: - - This operation can only be performed on Frameworks with type - ``CUSTOM``. Built-in Frameworks cannot be deleted. - - The Framework cannot be deleted if it is currently deployed on - any resource. - - This action is permanent and cannot be undone. + - You can't delete built-in frameworks. You can only delete + frameworks with type ``CUSTOM``. + - You can't delete frameworks that are deployed to a resource. + - You can't restore a deleted framework. This action is + permanent. Returns: Callable[[~.DeleteFrameworkRequest], @@ -503,10 +500,10 @@ def list_cloud_controls( ]: r"""Return a callable for the list cloud controls method over gRPC. - Lists all CloudControls (both Built-in and Custom) - available within a given parent resource. This method - supports pagination. The latest major version of each - CloudControl is returned. + Lists the cloud controls (both built-in and custom) + that are available in a given parent resource. The + latest major version of each cloud control is returned. + This method supports pagination. Returns: Callable[[~.ListCloudControlsRequest], @@ -532,13 +529,13 @@ def get_cloud_control( ) -> Callable[[config.GetCloudControlRequest], Awaitable[common.CloudControl]]: r"""Return a callable for the get cloud control method over gRPC. - Gets details of a single CloudControl. This method retrieves a - CloudControl resource, which can be either Built-in or Custom, - identified by its name. + Gets details about a cloud control. This method retrieves the + latest major version of a cloud control that you identify by + name. - By default, the latest major version of the CloudControl is - returned. A specific major version can be retrieved by - specifying the ``major_revision_id`` in the request. + By default, the latest major version of the cloud control is + returned. To retrieve a specific major version, include + ``major_revision_id`` in the request. Returns: Callable[[~.GetCloudControlRequest], @@ -564,9 +561,10 @@ def create_cloud_control( ) -> Callable[[config.CreateCloudControlRequest], Awaitable[common.CloudControl]]: r"""Return a callable for the create cloud control method over gRPC. - Creates a new CloudControl with type ``Custom`` under a given - parent resource. ``Built-in`` CloudControls are managed by - Google and cannot be created through this API. + Creates a custom cloud control in a given parent + resource. + You can't create built-in cloud controls because those + are managed by Google. Returns: Callable[[~.CreateCloudControlRequest], @@ -592,18 +590,18 @@ def update_cloud_control( ) -> Callable[[config.UpdateCloudControlRequest], Awaitable[common.CloudControl]]: r"""Return a callable for the update cloud control method over gRPC. - Updates a single CloudControl. This method allows for partial - updates of a Custom CloudControl resource. Built-in - CloudControls cannot be updated. + Updates a custom cloud control. This method allows for partial + updates of a cloud control. Use the ``update_mask`` to specify + which fields to update. Consider the following: - - If an ``update_mask`` is provided, only the fields specified - in the mask will be updated. - - If no ``update_mask`` is provided, all fields present in the - request's ``cloud_control`` body will be used to overwrite the - existing resource. + - If you provide an ``update_mask``, only the fields that are + specified in the mask are updated. + - If you don't provide an ``update_mask``, all the fields that + are present in the request's ``cloud_control`` body are used + to overwrite the existing resource. - A successful update will result in a new version of the - CloudControl. + You can only update cloud controls with the ``CUSTOM`` type. A + successful update creates a new version of the cloud control. Returns: Callable[[~.UpdateCloudControlRequest], @@ -629,14 +627,15 @@ def delete_cloud_control( ) -> Callable[[config.DeleteCloudControlRequest], Awaitable[empty_pb2.Empty]]: r"""Return a callable for the delete cloud control method over gRPC. - Deletes a single Custom CloudControl, including all its major - and minor revisions. + Deletes a custom cloud control, including all its major and + minor revisions. Consider the following: - - This operation can only be performed on CloudControls with - type ``CUSTOM``. Built-in CloudControls cannot be deleted. - - The CloudControl cannot be deleted if any of its revisions are - currently referenced by any Framework. - - This action is permanent and cannot be undone. + - You can't delete built-in cloud controls. You can only delete + cloud controls with type ``CUSTOM``. + - You can't delete cloud controls if any of the versions are + referenced by a framework. + - You can't restore a deleted cloud control. This action is + permanent. Returns: Callable[[~.DeleteCloudControlRequest], diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/rest.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/rest.py index 9ac64ea573f5..6d0b2e177e39 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/rest.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/config/transports/rest.py @@ -825,8 +825,7 @@ def __call__( Args: request (~.config.CreateCloudControlRequest): - The request object. Request message for creating a - CloudControl + The request object. The request message for [CreateCloudControl][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -837,14 +836,10 @@ def __call__( Returns: ~.common.CloudControl: - A CloudControl is the fundamental unit encapsulating the - rules to meet a specific security or compliance intent. - It can contain various rule types (like Organization - Policies, CEL expressions, etc.) enabling different - enforcement modes (Preventive, Detective, Audit). - CloudControls are often parameterized for reusability - and can be either BUILT_IN (provided by Google) or - CUSTOM (defined by the user). + A cloud control is a set of rules and + associated metadata that you can use to + define your organization's security or + compliance intent. """ @@ -990,8 +985,7 @@ def __call__( Args: request (~.config.CreateFrameworkRequest): - The request object. Request message for creating a - Framework + The request object. The request message for [CreateFramework][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1002,14 +996,11 @@ def __call__( Returns: ~.common.Framework: - A Framework is a collection of - CloudControls to address security and - compliance requirements. Frameworks can - be used for prevention, detection, and - auditing. They can be either built-in, - industry-standard frameworks provided by - GCP/AZURE/AWS (e.g., NIST, FedRAMP) or - custom frameworks created by users. + A framework is a collection of cloud + controls and regulatory controls that + represent security best practices or + industry-defined standards such as + FedRAMP or NIST. """ @@ -1154,8 +1145,7 @@ def __call__( Args: request (~.config.DeleteCloudControlRequest): - The request object. Request message for deleting a - CloudControl. + The request object. The request message for [DeleteCloudControl][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1265,8 +1255,7 @@ def __call__( Args: request (~.config.DeleteFrameworkRequest): - The request object. Request message for deleting a - Framework. + The request object. Request message for [DeleteFramework][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1378,8 +1367,7 @@ def __call__( Args: request (~.config.GetCloudControlRequest): - The request object. Request message for getting a - CloudControl. + The request object. The request message for [GetCloudControl][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1390,14 +1378,10 @@ def __call__( Returns: ~.common.CloudControl: - A CloudControl is the fundamental unit encapsulating the - rules to meet a specific security or compliance intent. - It can contain various rule types (like Organization - Policies, CEL expressions, etc.) enabling different - enforcement modes (Preventive, Detective, Audit). - CloudControls are often parameterized for reusability - and can be either BUILT_IN (provided by Google) or - CUSTOM (defined by the user). + A cloud control is a set of rules and + associated metadata that you can use to + define your organization's security or + compliance intent. """ @@ -1535,8 +1519,7 @@ def __call__( Args: request (~.config.GetFrameworkRequest): - The request object. Request message for getting a - Framework. + The request object. The request message for [GetFramework][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1547,14 +1530,11 @@ def __call__( Returns: ~.common.Framework: - A Framework is a collection of - CloudControls to address security and - compliance requirements. Frameworks can - be used for prevention, detection, and - auditing. They can be either built-in, - industry-standard frameworks provided by - GCP/AZURE/AWS (e.g., NIST, FedRAMP) or - custom frameworks created by users. + A framework is a collection of cloud + controls and regulatory controls that + represent security best practices or + industry-defined standards such as + FedRAMP or NIST. """ @@ -1692,8 +1672,7 @@ def __call__( Args: request (~.config.ListCloudControlsRequest): - The request object. Request message for listing - CloudControls. + The request object. Request message for [ListCloudControls][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1704,9 +1683,7 @@ def __call__( Returns: ~.config.ListCloudControlsResponse: - Response message for - ListCloudControls. - + The response message for [ListCloudControls][]. """ http_options = ( @@ -1845,8 +1822,7 @@ def __call__( Args: request (~.config.ListFrameworksRequest): - The request object. Request message for listing - Frameworks. + The request object. Request message for [ListFrameworks][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1857,9 +1833,8 @@ def __call__( Returns: ~.config.ListFrameworksResponse: - Response message for listing - Frameworks. Contains a paginated list of - Framework resources. + The response message for [ListFrameworks][]. Returns a + paginated list of Framework resources. """ @@ -1998,8 +1973,7 @@ def __call__( Args: request (~.config.UpdateCloudControlRequest): - The request object. Request message for - UpdateCloudControl. + The request object. The request message for [UpdateCloudControl][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -2010,14 +1984,10 @@ def __call__( Returns: ~.common.CloudControl: - A CloudControl is the fundamental unit encapsulating the - rules to meet a specific security or compliance intent. - It can contain various rule types (like Organization - Policies, CEL expressions, etc.) enabling different - enforcement modes (Preventive, Detective, Audit). - CloudControls are often parameterized for reusability - and can be either BUILT_IN (provided by Google) or - CUSTOM (defined by the user). + A cloud control is a set of rules and + associated metadata that you can use to + define your organization's security or + compliance intent. """ @@ -2163,8 +2133,7 @@ def __call__( Args: request (~.config.UpdateFrameworkRequest): - The request object. Request message for updating a - Framework. + The request object. The request message for [UpdateFramework][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -2175,14 +2144,11 @@ def __call__( Returns: ~.common.Framework: - A Framework is a collection of - CloudControls to address security and - compliance requirements. Frameworks can - be used for prevention, detection, and - auditing. They can be either built-in, - industry-standard frameworks provided by - GCP/AZURE/AWS (e.g., NIST, FedRAMP) or - custom frameworks created by users. + A framework is a collection of cloud + controls and regulatory controls that + represent security best practices or + industry-defined standards such as + FedRAMP or NIST. """ diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/async_client.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/async_client.py index 0f5b39b5747f..708af6987a97 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/async_client.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/async_client.py @@ -313,8 +313,11 @@ async def create_framework_deployment( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operation_async.AsyncOperation: - r"""Creates a new FrameworkDeployment in a given parent - resource. + r"""Creates a framework deployment in a given parent + resource. A framework deployment lets you assign a + particular framework version to an organization, folder, + or project so that you can control and monitor those + resources using the framework's cloud controls. .. code-block:: python @@ -356,29 +359,28 @@ async def sample_create_framework_deployment(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.CreateFrameworkDeploymentRequest, dict]]): - The request object. Request message for - CreateFrameworkDeployment API. + The request object. The request message for [CreateFrameworkDeployment][]. parent (:class:`str`): - Required. The parent resource of the - FrameworkDeployment in the format: - organizations/{organization}/locations/{location} - Only global location is supported. + Required. The parent resource of the framework + deployment in the format + ``organizations/{organization}/locations/{location}``. + Only the global location is supported. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. framework_deployment (:class:`google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeployment`): - Required. The FrameworkDeployment to - be created. + Required. The framework deployment + that you're creating. This corresponds to the ``framework_deployment`` field on the ``request`` instance; if ``request`` is provided, this should not be set. framework_deployment_id (:class:`str`): - Optional. User provided identifier. - It should be unique in scope of a - parent. This is optional and if not - provided, a random UUID will be + Optional. An identifier for the + framework deployment that's unique in + scope of the parent. If you don't + specify a value, then a random UUID is generated. This corresponds to the ``framework_deployment_id`` field @@ -396,10 +398,9 @@ async def sample_create_framework_deployment(): google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be :class:`google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeployment` FrameworkDeployment represents deployment of a Framework on a target + The result type for the operation will be :class:`google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeployment` Framework deployments represent the assignment of a framework to a target resource. Supported target resources are - organizations/{organization}, folders/{folder}, and - projects/{project}. + organizations, folders, and projects. """ # Create or coerce a protobuf request object. @@ -474,7 +475,7 @@ async def delete_framework_deployment( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operation_async.AsyncOperation: - r"""Deletes a single FrameworkDeployment. + r"""Deletes a framework deployment. .. code-block:: python @@ -508,12 +509,12 @@ async def sample_delete_framework_deployment(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.DeleteFrameworkDeploymentRequest, dict]]): - The request object. Request message for - DeleteFrameworkDeployment. + The request object. The request message for [DeleteFrameworkDeployment][]. name (:class:`str`): - Required. name of the FrameworkDeployment to be deleted - in the following format: - organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id} + Required. The name of the framework deployment that you + want to delete, in the format + ``organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -608,7 +609,7 @@ async def get_framework_deployment( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> deployment.FrameworkDeployment: - r"""Gets details of a single FrameworkDeployment. + r"""Gets details about a framework deployment. .. code-block:: python @@ -638,12 +639,12 @@ async def sample_get_framework_deployment(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.GetFrameworkDeploymentRequest, dict]]): - The request object. Request message for - GetFrameworkDeployment. + The request object. The request message for [GetFrameworkDeployment][]. name (:class:`str`): - Required. FrameworkDeployment name in the following - format: - organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id} + Required. The name of the framework deployment, in the + format + ``organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -658,12 +659,10 @@ async def sample_get_framework_deployment(): Returns: google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeployment: - FrameworkDeployment represents - deployment of a Framework on a target + Framework deployments represent the + assignment of a framework to a target resource. Supported target resources are - organizations/{organization}, - folders/{folder}, and - projects/{project}. + organizations, folders, and projects. """ # Create or coerce a protobuf request object. @@ -726,7 +725,7 @@ async def list_framework_deployments( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListFrameworkDeploymentsAsyncPager: - r"""Lists FrameworkDeployments in a given parent + r"""Lists the framework deployments in a given parent resource. .. code-block:: python @@ -758,13 +757,12 @@ async def sample_list_framework_deployments(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkDeploymentsRequest, dict]]): - The request object. Request message for - ListFrameworkDeployments. + The request object. The request message for [ListFrameworkDeployments][]. parent (:class:`str`): - Required. parent resource of the - FrameworkDeployment in the format: - organizations/{organization}/locations/{location} - Only global location is supported. + Required. The parent resource of the framework + deployment, in the format + ``organizations/{organization}/locations/{location}``. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -779,11 +777,10 @@ async def sample_list_framework_deployments(): Returns: google.cloud.cloudsecuritycompliance_v1.services.deployment.pagers.ListFrameworkDeploymentsAsyncPager: - Response message for - ListFrameworkDeployments. - Iterating over this object will yield - results and resolve additional pages - automatically. + The response message for [ListFrameworkDeployments][]. + + Iterating over this object will yield results and + resolve additional pages automatically. """ # Create or coerce a protobuf request object. @@ -857,7 +854,7 @@ async def get_cloud_control_deployment( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> deployment.CloudControlDeployment: - r"""Gets details of a single CloudControlDeployment. + r"""Gets details about a cloud control deployment. .. code-block:: python @@ -887,12 +884,12 @@ async def sample_get_cloud_control_deployment(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.GetCloudControlDeploymentRequest, dict]]): - The request object. Request message for - GetCloudControlDeployment. + The request object. The request message for [GetCloudControlDeployment][]. name (:class:`str`): - Required. CloudControlDeployment name in the following - format: - organizations/{organization}/locations/{location}/cloudControlDeployments/{cloud_control_deployment_id} + Required. The name for the cloud control deployment, in + the format + ``organizations/{organization}/locations/{location}/cloudControlDeployments/{cloud_control_deployment_id}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -907,12 +904,10 @@ async def sample_get_cloud_control_deployment(): Returns: google.cloud.cloudsecuritycompliance_v1.types.CloudControlDeployment: - CloudControlDeployment represents - deployment of a CloudControl on a target - resource. Supported target resources are - organizations/{organization}, - folders/{folder}, and - projects/{project}. + A cloud control deployment represents the deployment of a particular cloud + control on a target resource. Supported target + resources are organizations/{organizationID}, + folders/{folderID}, and projects/{projectID}. """ # Create or coerce a protobuf request object. @@ -975,7 +970,7 @@ async def list_cloud_control_deployments( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListCloudControlDeploymentsAsyncPager: - r"""Lists CloudControlDeployments in a given parent + r"""Lists the cloud conrol deployments in a given parent resource. .. code-block:: python @@ -1007,13 +1002,12 @@ async def sample_list_cloud_control_deployments(): Args: request (Optional[Union[google.cloud.cloudsecuritycompliance_v1.types.ListCloudControlDeploymentsRequest, dict]]): - The request object. Request message for - ListCloudControlDeployments. + The request object. The request message for [ListCloudControlDeployments][]. parent (:class:`str`): - Required. parent resource of the - CloudControlDeployment in the format: - organizations/{organization}/locations/{location} - Only global location is supported. + Required. The parent resource for the cloud control + deployment, in the format + ``organizations/{organization}/locations/{location}``. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -1028,11 +1022,11 @@ async def sample_list_cloud_control_deployments(): Returns: google.cloud.cloudsecuritycompliance_v1.services.deployment.pagers.ListCloudControlDeploymentsAsyncPager: - Response message for - ListCloudControlDeployments. - Iterating over this object will yield - results and resolve additional pages - automatically. + The response message for + [ListCloudControlDeployments][]. + + Iterating over this object will yield results and + resolve additional pages automatically. """ # Create or coerce a protobuf request object. diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/client.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/client.py index ed48d3c7faa8..0bae022d616d 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/client.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/client.py @@ -771,8 +771,11 @@ def create_framework_deployment( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operation.Operation: - r"""Creates a new FrameworkDeployment in a given parent - resource. + r"""Creates a framework deployment in a given parent + resource. A framework deployment lets you assign a + particular framework version to an organization, folder, + or project so that you can control and monitor those + resources using the framework's cloud controls. .. code-block:: python @@ -814,29 +817,28 @@ def sample_create_framework_deployment(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.CreateFrameworkDeploymentRequest, dict]): - The request object. Request message for - CreateFrameworkDeployment API. + The request object. The request message for [CreateFrameworkDeployment][]. parent (str): - Required. The parent resource of the - FrameworkDeployment in the format: - organizations/{organization}/locations/{location} - Only global location is supported. + Required. The parent resource of the framework + deployment in the format + ``organizations/{organization}/locations/{location}``. + Only the global location is supported. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this should not be set. framework_deployment (google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeployment): - Required. The FrameworkDeployment to - be created. + Required. The framework deployment + that you're creating. This corresponds to the ``framework_deployment`` field on the ``request`` instance; if ``request`` is provided, this should not be set. framework_deployment_id (str): - Optional. User provided identifier. - It should be unique in scope of a - parent. This is optional and if not - provided, a random UUID will be + Optional. An identifier for the + framework deployment that's unique in + scope of the parent. If you don't + specify a value, then a random UUID is generated. This corresponds to the ``framework_deployment_id`` field @@ -854,10 +856,9 @@ def sample_create_framework_deployment(): google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be :class:`google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeployment` FrameworkDeployment represents deployment of a Framework on a target + The result type for the operation will be :class:`google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeployment` Framework deployments represent the assignment of a framework to a target resource. Supported target resources are - organizations/{organization}, folders/{folder}, and - projects/{project}. + organizations, folders, and projects. """ # Create or coerce a protobuf request object. @@ -931,7 +932,7 @@ def delete_framework_deployment( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operation.Operation: - r"""Deletes a single FrameworkDeployment. + r"""Deletes a framework deployment. .. code-block:: python @@ -965,12 +966,12 @@ def sample_delete_framework_deployment(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.DeleteFrameworkDeploymentRequest, dict]): - The request object. Request message for - DeleteFrameworkDeployment. + The request object. The request message for [DeleteFrameworkDeployment][]. name (str): - Required. name of the FrameworkDeployment to be deleted - in the following format: - organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id} + Required. The name of the framework deployment that you + want to delete, in the format + ``organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1064,7 +1065,7 @@ def get_framework_deployment( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> deployment.FrameworkDeployment: - r"""Gets details of a single FrameworkDeployment. + r"""Gets details about a framework deployment. .. code-block:: python @@ -1094,12 +1095,12 @@ def sample_get_framework_deployment(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.GetFrameworkDeploymentRequest, dict]): - The request object. Request message for - GetFrameworkDeployment. + The request object. The request message for [GetFrameworkDeployment][]. name (str): - Required. FrameworkDeployment name in the following - format: - organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id} + Required. The name of the framework deployment, in the + format + ``organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1114,12 +1115,10 @@ def sample_get_framework_deployment(): Returns: google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeployment: - FrameworkDeployment represents - deployment of a Framework on a target + Framework deployments represent the + assignment of a framework to a target resource. Supported target resources are - organizations/{organization}, - folders/{folder}, and - projects/{project}. + organizations, folders, and projects. """ # Create or coerce a protobuf request object. @@ -1179,7 +1178,7 @@ def list_framework_deployments( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListFrameworkDeploymentsPager: - r"""Lists FrameworkDeployments in a given parent + r"""Lists the framework deployments in a given parent resource. .. code-block:: python @@ -1211,13 +1210,12 @@ def sample_list_framework_deployments(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkDeploymentsRequest, dict]): - The request object. Request message for - ListFrameworkDeployments. + The request object. The request message for [ListFrameworkDeployments][]. parent (str): - Required. parent resource of the - FrameworkDeployment in the format: - organizations/{organization}/locations/{location} - Only global location is supported. + Required. The parent resource of the framework + deployment, in the format + ``organizations/{organization}/locations/{location}``. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -1232,11 +1230,10 @@ def sample_list_framework_deployments(): Returns: google.cloud.cloudsecuritycompliance_v1.services.deployment.pagers.ListFrameworkDeploymentsPager: - Response message for - ListFrameworkDeployments. - Iterating over this object will yield - results and resolve additional pages - automatically. + The response message for [ListFrameworkDeployments][]. + + Iterating over this object will yield results and + resolve additional pages automatically. """ # Create or coerce a protobuf request object. @@ -1309,7 +1306,7 @@ def get_cloud_control_deployment( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> deployment.CloudControlDeployment: - r"""Gets details of a single CloudControlDeployment. + r"""Gets details about a cloud control deployment. .. code-block:: python @@ -1339,12 +1336,12 @@ def sample_get_cloud_control_deployment(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.GetCloudControlDeploymentRequest, dict]): - The request object. Request message for - GetCloudControlDeployment. + The request object. The request message for [GetCloudControlDeployment][]. name (str): - Required. CloudControlDeployment name in the following - format: - organizations/{organization}/locations/{location}/cloudControlDeployments/{cloud_control_deployment_id} + Required. The name for the cloud control deployment, in + the format + ``organizations/{organization}/locations/{location}/cloudControlDeployments/{cloud_control_deployment_id}``. + The only supported location is ``global``. This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this @@ -1359,12 +1356,10 @@ def sample_get_cloud_control_deployment(): Returns: google.cloud.cloudsecuritycompliance_v1.types.CloudControlDeployment: - CloudControlDeployment represents - deployment of a CloudControl on a target - resource. Supported target resources are - organizations/{organization}, - folders/{folder}, and - projects/{project}. + A cloud control deployment represents the deployment of a particular cloud + control on a target resource. Supported target + resources are organizations/{organizationID}, + folders/{folderID}, and projects/{projectID}. """ # Create or coerce a protobuf request object. @@ -1426,7 +1421,7 @@ def list_cloud_control_deployments( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListCloudControlDeploymentsPager: - r"""Lists CloudControlDeployments in a given parent + r"""Lists the cloud conrol deployments in a given parent resource. .. code-block:: python @@ -1458,13 +1453,12 @@ def sample_list_cloud_control_deployments(): Args: request (Union[google.cloud.cloudsecuritycompliance_v1.types.ListCloudControlDeploymentsRequest, dict]): - The request object. Request message for - ListCloudControlDeployments. + The request object. The request message for [ListCloudControlDeployments][]. parent (str): - Required. parent resource of the - CloudControlDeployment in the format: - organizations/{organization}/locations/{location} - Only global location is supported. + Required. The parent resource for the cloud control + deployment, in the format + ``organizations/{organization}/locations/{location}``. + The only supported location is ``global``. This corresponds to the ``parent`` field on the ``request`` instance; if ``request`` is provided, this @@ -1479,11 +1473,11 @@ def sample_list_cloud_control_deployments(): Returns: google.cloud.cloudsecuritycompliance_v1.services.deployment.pagers.ListCloudControlDeploymentsPager: - Response message for - ListCloudControlDeployments. - Iterating over this object will yield - results and resolve additional pages - automatically. + The response message for + [ListCloudControlDeployments][]. + + Iterating over this object will yield results and + resolve additional pages automatically. """ # Create or coerce a protobuf request object. diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/grpc.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/grpc.py index 971c4740f478..424683773525 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/grpc.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/grpc.py @@ -349,8 +349,11 @@ def create_framework_deployment( ]: r"""Return a callable for the create framework deployment method over gRPC. - Creates a new FrameworkDeployment in a given parent - resource. + Creates a framework deployment in a given parent + resource. A framework deployment lets you assign a + particular framework version to an organization, folder, + or project so that you can control and monitor those + resources using the framework's cloud controls. Returns: Callable[[~.CreateFrameworkDeploymentRequest], @@ -380,7 +383,7 @@ def delete_framework_deployment( ]: r"""Return a callable for the delete framework deployment method over gRPC. - Deletes a single FrameworkDeployment. + Deletes a framework deployment. Returns: Callable[[~.DeleteFrameworkDeploymentRequest], @@ -410,7 +413,7 @@ def get_framework_deployment( ]: r"""Return a callable for the get framework deployment method over gRPC. - Gets details of a single FrameworkDeployment. + Gets details about a framework deployment. Returns: Callable[[~.GetFrameworkDeploymentRequest], @@ -439,7 +442,7 @@ def list_framework_deployments( ]: r"""Return a callable for the list framework deployments method over gRPC. - Lists FrameworkDeployments in a given parent + Lists the framework deployments in a given parent resource. Returns: @@ -470,7 +473,7 @@ def get_cloud_control_deployment( ]: r"""Return a callable for the get cloud control deployment method over gRPC. - Gets details of a single CloudControlDeployment. + Gets details about a cloud control deployment. Returns: Callable[[~.GetCloudControlDeploymentRequest], @@ -501,7 +504,7 @@ def list_cloud_control_deployments( ]: r"""Return a callable for the list cloud control deployments method over gRPC. - Lists CloudControlDeployments in a given parent + Lists the cloud conrol deployments in a given parent resource. Returns: diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/grpc_asyncio.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/grpc_asyncio.py index f9730e985b13..3ae8033159f6 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/grpc_asyncio.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/grpc_asyncio.py @@ -358,8 +358,11 @@ def create_framework_deployment( ]: r"""Return a callable for the create framework deployment method over gRPC. - Creates a new FrameworkDeployment in a given parent - resource. + Creates a framework deployment in a given parent + resource. A framework deployment lets you assign a + particular framework version to an organization, folder, + or project so that you can control and monitor those + resources using the framework's cloud controls. Returns: Callable[[~.CreateFrameworkDeploymentRequest], @@ -390,7 +393,7 @@ def delete_framework_deployment( ]: r"""Return a callable for the delete framework deployment method over gRPC. - Deletes a single FrameworkDeployment. + Deletes a framework deployment. Returns: Callable[[~.DeleteFrameworkDeploymentRequest], @@ -421,7 +424,7 @@ def get_framework_deployment( ]: r"""Return a callable for the get framework deployment method over gRPC. - Gets details of a single FrameworkDeployment. + Gets details about a framework deployment. Returns: Callable[[~.GetFrameworkDeploymentRequest], @@ -450,7 +453,7 @@ def list_framework_deployments( ]: r"""Return a callable for the list framework deployments method over gRPC. - Lists FrameworkDeployments in a given parent + Lists the framework deployments in a given parent resource. Returns: @@ -482,7 +485,7 @@ def get_cloud_control_deployment( ]: r"""Return a callable for the get cloud control deployment method over gRPC. - Gets details of a single CloudControlDeployment. + Gets details about a cloud control deployment. Returns: Callable[[~.GetCloudControlDeploymentRequest], @@ -513,7 +516,7 @@ def list_cloud_control_deployments( ]: r"""Return a callable for the list cloud control deployments method over gRPC. - Lists CloudControlDeployments in a given parent + Lists the cloud conrol deployments in a given parent resource. Returns: diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/rest.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/rest.py index 17353368f2c8..d62b139180f0 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/rest.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/services/deployment/transports/rest.py @@ -761,8 +761,7 @@ def __call__( Args: request (~.deployment.CreateFrameworkDeploymentRequest): - The request object. Request message for - CreateFrameworkDeployment API. + The request object. The request message for [CreateFrameworkDeployment][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -915,8 +914,7 @@ def __call__( Args: request (~.deployment.DeleteFrameworkDeploymentRequest): - The request object. Request message for - DeleteFrameworkDeployment. + The request object. The request message for [DeleteFrameworkDeployment][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1064,8 +1062,7 @@ def __call__( Args: request (~.deployment.GetCloudControlDeploymentRequest): - The request object. Request message for - GetCloudControlDeployment. + The request object. The request message for [GetCloudControlDeployment][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1076,12 +1073,11 @@ def __call__( Returns: ~.deployment.CloudControlDeployment: - CloudControlDeployment represents - deployment of a CloudControl on a target - resource. Supported target resources are - organizations/{organization}, - folders/{folder}, and - projects/{project}. + A cloud control deployment represents the deployment of + a particular cloud control on a target resource. + Supported target resources are + ``organizations/{organizationID}``, + ``folders/{folderID}``, and ``projects/{projectID}``. """ @@ -1219,8 +1215,7 @@ def __call__( Args: request (~.deployment.GetFrameworkDeploymentRequest): - The request object. Request message for - GetFrameworkDeployment. + The request object. The request message for [GetFrameworkDeployment][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1231,12 +1226,10 @@ def __call__( Returns: ~.deployment.FrameworkDeployment: - FrameworkDeployment represents - deployment of a Framework on a target + Framework deployments represent the + assignment of a framework to a target resource. Supported target resources are - organizations/{organization}, - folders/{folder}, and - projects/{project}. + organizations, folders, and projects. """ @@ -1374,8 +1367,7 @@ def __call__( Args: request (~.deployment.ListCloudControlDeploymentsRequest): - The request object. Request message for - ListCloudControlDeployments. + The request object. The request message for [ListCloudControlDeployments][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1386,8 +1378,8 @@ def __call__( Returns: ~.deployment.ListCloudControlDeploymentsResponse: - Response message for - ListCloudControlDeployments. + The response message for + [ListCloudControlDeployments][]. """ @@ -1531,8 +1523,7 @@ def __call__( Args: request (~.deployment.ListFrameworkDeploymentsRequest): - The request object. Request message for - ListFrameworkDeployments. + The request object. The request message for [ListFrameworkDeployments][]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1543,9 +1534,7 @@ def __call__( Returns: ~.deployment.ListFrameworkDeploymentsResponse: - Response message for - ListFrameworkDeployments. - + The response message for [ListFrameworkDeployments][]. """ http_options = ( diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/__init__.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/__init__.py index 2fcf1cee660e..d7bedb6888fa 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/__init__.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/__init__.py @@ -13,6 +13,31 @@ # See the License for the specific language governing permissions and # limitations under the License. # +from .audit import ( + BucketDestination, + CloudControlAuditDetails, + CloudControlGroupAuditDetails, + ComplianceState, + CreateFrameworkAuditRequest, + EvidenceDetails, + FindingDetails, + FrameworkAudit, + FrameworkAuditDestination, + GenerateFrameworkAuditScopeReportRequest, + GenerateFrameworkAuditScopeReportResponse, + GetFrameworkAuditRequest, + ListFrameworkAuditsRequest, + ListFrameworkAuditsResponse, + ObservationDetails, + ReportSummary, +) +from .cm_enrollment_service import ( + AuditConfig, + CalculateEffectiveCmEnrollmentRequest, + CalculateEffectiveCmEnrollmentResponse, + CmEnrollment, + UpdateCmEnrollmentRequest, +) from .common import ( AllowedValues, AttributeSubstitutionRule, @@ -21,6 +46,7 @@ CloudControlCategory, CloudControlDetails, CloudProvider, + ControlFamily, EnforcementMode, Framework, FrameworkCategory, @@ -33,6 +59,7 @@ ParamValue, PlaceholderSubstitutionRule, RegexpPattern, + RegulatoryControlResponsibilityType, Rule, RuleActionType, Severity, @@ -76,11 +103,33 @@ ) __all__ = ( + "BucketDestination", + "CloudControlAuditDetails", + "CloudControlGroupAuditDetails", + "CreateFrameworkAuditRequest", + "EvidenceDetails", + "FindingDetails", + "FrameworkAudit", + "FrameworkAuditDestination", + "GenerateFrameworkAuditScopeReportRequest", + "GenerateFrameworkAuditScopeReportResponse", + "GetFrameworkAuditRequest", + "ListFrameworkAuditsRequest", + "ListFrameworkAuditsResponse", + "ObservationDetails", + "ReportSummary", + "ComplianceState", + "AuditConfig", + "CalculateEffectiveCmEnrollmentRequest", + "CalculateEffectiveCmEnrollmentResponse", + "CmEnrollment", + "UpdateCmEnrollmentRequest", "AllowedValues", "AttributeSubstitutionRule", "CELExpression", "CloudControl", "CloudControlDetails", + "ControlFamily", "Framework", "FrameworkReference", "IntRange", @@ -98,6 +147,7 @@ "CloudProvider", "EnforcementMode", "FrameworkCategory", + "RegulatoryControlResponsibilityType", "RuleActionType", "Severity", "TargetResourceType", diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/audit.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/audit.py new file mode 100644 index 000000000000..96053402b325 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/audit.py @@ -0,0 +1,762 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.types import common + +__protobuf__ = proto.module( + package="google.cloud.cloudsecuritycompliance.v1", + manifest={ + "ComplianceState", + "GenerateFrameworkAuditScopeReportRequest", + "GenerateFrameworkAuditScopeReportResponse", + "ReportSummary", + "CreateFrameworkAuditRequest", + "FrameworkAuditDestination", + "BucketDestination", + "FrameworkAudit", + "ListFrameworkAuditsRequest", + "ListFrameworkAuditsResponse", + "GetFrameworkAuditRequest", + "CloudControlGroupAuditDetails", + "FindingDetails", + "ObservationDetails", + "EvidenceDetails", + "CloudControlAuditDetails", + }, +) + + +class ComplianceState(proto.Enum): + r"""The state of compliance after evaluation is complete. + + Values: + COMPLIANCE_STATE_UNSPECIFIED (0): + Default value. This value is unused. + COMPLIANT (1): + The resource is compliant. + VIOLATION (2): + The resource has a violation. + MANUAL_REVIEW_NEEDED (3): + The resource requires manual review from you. + ERROR (4): + An error occurred while computing the + resource status. + AUDIT_NOT_SUPPORTED (5): + The resource can't be audited. + """ + COMPLIANCE_STATE_UNSPECIFIED = 0 + COMPLIANT = 1 + VIOLATION = 2 + MANUAL_REVIEW_NEEDED = 3 + ERROR = 4 + AUDIT_NOT_SUPPORTED = 5 + + +class GenerateFrameworkAuditScopeReportRequest(proto.Message): + r"""The request message for [GenerateFrameworkAuditScopeReport][]. + + Attributes: + scope (str): + Required. The organization, folder or project for the audit + report. + + Supported formats are the following: + + - ``projects/{project_id}/locations/{location}`` + - ``folders/{folder_id}/locations/{location}`` + - ``organizations/{organization_id}/locations/{location}`` + report_format (google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportRequest.Format): + Required. The format that the scope report + bytes is returned in. + compliance_framework (str): + Required. The compliance framework that the + scope report is generated for. + """ + + class Format(proto.Enum): + r"""The set of options for the audit scope report format. + + Values: + FORMAT_UNSPECIFIED (0): + Default value. This value is unused. + ODF (1): + The report format is the Open Document Format + (ODF). + """ + FORMAT_UNSPECIFIED = 0 + ODF = 1 + + scope: str = proto.Field( + proto.STRING, + number=1, + ) + report_format: Format = proto.Field( + proto.ENUM, + number=2, + enum=Format, + ) + compliance_framework: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GenerateFrameworkAuditScopeReportResponse(proto.Message): + r"""The response message for [GenerateFrameworkAuditScopeReport][]. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + scope_report_contents (bytes): + The audit scope report content in byte + format. + + This field is a member of `oneof`_ ``audit_report``. + name (str): + Identifier. The name of the audit report, in + the format that was given in the request. + compliance_framework (str): + Required. The compliance framework that the + audit scope report is generated for. + """ + + scope_report_contents: bytes = proto.Field( + proto.BYTES, + number=3, + oneof="audit_report", + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + compliance_framework: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ReportSummary(proto.Message): + r"""Additional information for an audit operation. + + Attributes: + total_count (int): + Output only. The total number of checks. + compliant_count (int): + Output only. The number of compliant checks. + violation_count (int): + Output only. The number of checks with + violations. + manual_review_needed_count (int): + Output only. The number of checks with + "manual review needed" status. + error_count (int): + Output only. The number of checks that can't + be performed due to errors. + """ + + total_count: int = proto.Field( + proto.INT32, + number=1, + ) + compliant_count: int = proto.Field( + proto.INT32, + number=2, + ) + violation_count: int = proto.Field( + proto.INT32, + number=3, + ) + manual_review_needed_count: int = proto.Field( + proto.INT32, + number=4, + ) + error_count: int = proto.Field( + proto.INT32, + number=5, + ) + + +class CreateFrameworkAuditRequest(proto.Message): + r"""The request message for [CreateFrameworkAudit][]. + + Attributes: + parent (str): + Required. The parent resource where this framework audit is + created. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}`` + - ``folders/{folder_id}/locations/{location}`` + - ``projects/{project_id}/locations/{location}`` + framework_audit_id (str): + Optional. The ID to use for the framework audit. The ID + becomes the final component of the framework audit's full + resource name. + + The ID must be between 4-63 characters, and valid characters + are ``\[a-z][0-9]-\``. + framework_audit (google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit): + Required. The framework audit to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + framework_audit_id: str = proto.Field( + proto.STRING, + number=2, + ) + framework_audit: "FrameworkAudit" = proto.Field( + proto.MESSAGE, + number=3, + message="FrameworkAudit", + ) + + +class FrameworkAuditDestination(proto.Message): + r"""A destination for the framework audit. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + bucket (google.cloud.cloudsecuritycompliance_v1.types.BucketDestination): + The Cloud Storage bucket destination. + + This field is a member of `oneof`_ ``destination_type``. + """ + + bucket: "BucketDestination" = proto.Field( + proto.MESSAGE, + number=1, + oneof="destination_type", + message="BucketDestination", + ) + + +class BucketDestination(proto.Message): + r"""A Cloud Storage bucket destination. + + Attributes: + bucket_uri (str): + Required. The URI of the Cloud Storage + bucket. + framework_audit_format (google.cloud.cloudsecuritycompliance_v1.types.BucketDestination.Format): + Optional. The format of the framework audit. + """ + + class Format(proto.Enum): + r"""The set of options for the framework audit format. + + Values: + FORMAT_UNSPECIFIED (0): + Default value. This value is unused. + ODF (1): + The format for the framework audit report is + Open Document. + """ + FORMAT_UNSPECIFIED = 0 + ODF = 1 + + bucket_uri: str = proto.Field( + proto.STRING, + number=1, + ) + framework_audit_format: Format = proto.Field( + proto.ENUM, + number=3, + enum=Format, + ) + + +class FrameworkAudit(proto.Message): + r"""A framework audit. + + Attributes: + name (str): + Output only. Identifier. The name of the + framework audit. + framework_audit_id (str): + Output only. The ID of the framework audit. + compliance_framework (str): + Output only. The compliance framework used + for the audit. + scope (str): + Output only. The scope of the audit. + framework_audit_destination (google.cloud.cloudsecuritycompliance_v1.types.FrameworkAuditDestination): + Required. The destination for the audit + reports. + start_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time that the audit started. + finish_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time that the audit + finished. + compliance_state (google.cloud.cloudsecuritycompliance_v1.types.ComplianceState): + Output only. The overall compliance state of + the audit. + report_summary (google.cloud.cloudsecuritycompliance_v1.types.ReportSummary): + Output only. The summary of the report. + cloud_control_group_audit_details (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudControlGroupAuditDetails]): + Optional. The details for the cloud control + groups within this audit. + cloud_control_audit_details (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudControlAuditDetails]): + Optional. The details for the cloud controls + within this audit. + operation_id (str): + Output only. The ID of the long-running + operation. + state (google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit.State): + Output only. The framework audit state of the + audit. + """ + + class State(proto.Enum): + r"""The state of the framework audit. + + Values: + STATE_UNSPECIFIED (0): + Default value. This value is unused. + SCHEDULED (1): + The audit is scheduled. + RUNNING (2): + The audit is running. + UPLOADING (3): + The audit results are being uploaded. + FAILED (4): + The audit failed. + SUCCEEDED (5): + The audit completed successfully. + """ + STATE_UNSPECIFIED = 0 + SCHEDULED = 1 + RUNNING = 2 + UPLOADING = 3 + FAILED = 4 + SUCCEEDED = 5 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + framework_audit_id: str = proto.Field( + proto.STRING, + number=2, + ) + compliance_framework: str = proto.Field( + proto.STRING, + number=3, + ) + scope: str = proto.Field( + proto.STRING, + number=4, + ) + framework_audit_destination: "FrameworkAuditDestination" = proto.Field( + proto.MESSAGE, + number=5, + message="FrameworkAuditDestination", + ) + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + finish_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + compliance_state: "ComplianceState" = proto.Field( + proto.ENUM, + number=8, + enum="ComplianceState", + ) + report_summary: "ReportSummary" = proto.Field( + proto.MESSAGE, + number=9, + message="ReportSummary", + ) + cloud_control_group_audit_details: MutableSequence[ + "CloudControlGroupAuditDetails" + ] = proto.RepeatedField( + proto.MESSAGE, + number=10, + message="CloudControlGroupAuditDetails", + ) + cloud_control_audit_details: MutableSequence[ + "CloudControlAuditDetails" + ] = proto.RepeatedField( + proto.MESSAGE, + number=11, + message="CloudControlAuditDetails", + ) + operation_id: str = proto.Field( + proto.STRING, + number=12, + ) + state: State = proto.Field( + proto.ENUM, + number=13, + enum=State, + ) + + +class ListFrameworkAuditsRequest(proto.Message): + r"""The request message for [ListFrameworkAudits][]. + + Attributes: + parent (str): + Required. The parent resource where the framework audits are + listed. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}`` + - ``folders/{folder_id}/locations/{location}`` + - ``projects/{project_id}/locations/{location}`` + page_size (int): + Optional. The maximum number of framework + audits to return. The service might return fewer + audits than this value. If unspecified, a + maximum of 10 framework audits are returned. The + maximum value is 50; values above 50 are limited + to 50. + page_token (str): + Optional. The ``next_page_token`` value that's returned from + a previous list request, if any. + filter (str): + Optional. The filters to apply to the framework audits. + Supported filters are ``compliance_framework``, + ``compliance_state``, ``create_time,`` and + ``framework_audit_name``. If the filter is invalid, an + invalid argument error is returned. For syntax details, see + [AIP-160][https://google.aip.dev/160]. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListFrameworkAuditsResponse(proto.Message): + r"""The response message for [ListFrameworkAudits][]. + + Attributes: + framework_audits (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit]): + The framework audits. + next_page_token (str): + A token, which you can send as the ``page_token`` to + retrieve the next page. If this field is omitted, there are + no subsequent pages. + """ + + @property + def raw_page(self): + return self + + framework_audits: MutableSequence["FrameworkAudit"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="FrameworkAudit", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetFrameworkAuditRequest(proto.Message): + r"""The request message for [GetFrameworkAudit][]. + + Attributes: + name (str): + Required. The name of the framework audit to retrieve. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}/frameworkAudits/{frameworkAuditName}`` + - ``folders/{folder_id}/locations/{location}/frameworkAudits/{frameworkAuditName}`` + - ``projects/{project_id}/locations/{location}/frameworkAudits/{frameworkAuditName}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CloudControlGroupAuditDetails(proto.Message): + r"""The details for a cloud control group. + + Attributes: + cloud_control_group_id (str): + Output only. The ID of the cloud control + group. + display_name (str): + Output only. The display name of the cloud + control group. + description (str): + Output only. The description of the cloud + control group. + responsibility_type (str): + Output only. The responsibility type. + google_responsibility_description (str): + Output only. The description of Google's + responsibility. + google_responsibility_implementation (str): + Output only. The implementation of Google's + responsibility. + customer_responsibility_description (str): + Output only. The description of your + responsibility. + customer_responsibility_implementation (str): + Output only. The implementation of your + responsibility. + compliance_state (google.cloud.cloudsecuritycompliance_v1.types.ComplianceState): + Output only. The compliance state of the + control group. + control_id (str): + Output only. The ID of the regulatory + control. + control_family (google.cloud.cloudsecuritycompliance_v1.types.ControlFamily): + Output only. The control family. + cloud_control_details (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudControlAuditDetails]): + Output only. The details for the cloud + controls within this group. + report_summary (google.cloud.cloudsecuritycompliance_v1.types.ReportSummary): + Output only. The summary of the report. + """ + + cloud_control_group_id: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + responsibility_type: str = proto.Field( + proto.STRING, + number=4, + ) + google_responsibility_description: str = proto.Field( + proto.STRING, + number=5, + ) + google_responsibility_implementation: str = proto.Field( + proto.STRING, + number=6, + ) + customer_responsibility_description: str = proto.Field( + proto.STRING, + number=7, + ) + customer_responsibility_implementation: str = proto.Field( + proto.STRING, + number=8, + ) + compliance_state: "ComplianceState" = proto.Field( + proto.ENUM, + number=9, + enum="ComplianceState", + ) + control_id: str = proto.Field( + proto.STRING, + number=10, + ) + control_family: common.ControlFamily = proto.Field( + proto.MESSAGE, + number=11, + message=common.ControlFamily, + ) + cloud_control_details: MutableSequence[ + "CloudControlAuditDetails" + ] = proto.RepeatedField( + proto.MESSAGE, + number=12, + message="CloudControlAuditDetails", + ) + report_summary: "ReportSummary" = proto.Field( + proto.MESSAGE, + number=13, + message="ReportSummary", + ) + + +class FindingDetails(proto.Message): + r"""The details for a finding. + + Attributes: + name (str): + Output only. The name of the finding. + compliance_state (google.cloud.cloudsecuritycompliance_v1.types.ComplianceState): + Output only. The compliance state of the + finding. + observation (google.cloud.cloudsecuritycompliance_v1.types.ObservationDetails): + Output only. The observation details for the + finding. + evidence (google.cloud.cloudsecuritycompliance_v1.types.EvidenceDetails): + Output only. The evidence details for the + finding. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + compliance_state: "ComplianceState" = proto.Field( + proto.ENUM, + number=2, + enum="ComplianceState", + ) + observation: "ObservationDetails" = proto.Field( + proto.MESSAGE, + number=3, + message="ObservationDetails", + ) + evidence: "EvidenceDetails" = proto.Field( + proto.MESSAGE, + number=4, + message="EvidenceDetails", + ) + + +class ObservationDetails(proto.Message): + r"""The observation details for a finding. + + Attributes: + current_value (str): + Output only. The current value. + expected_value (str): + Optional. The expected value. + guidance (str): + Output only. Any guidance for the + observation. + """ + + current_value: str = proto.Field( + proto.STRING, + number=1, + ) + expected_value: str = proto.Field( + proto.STRING, + number=2, + ) + guidance: str = proto.Field( + proto.STRING, + number=3, + ) + + +class EvidenceDetails(proto.Message): + r"""The evidence details for a finding. + + Attributes: + resource (str): + Output only. The resource identifier. + service (str): + Output only. The service identifier. + evidence_path (str): + Output only. The path to the evidence. + """ + + resource: str = proto.Field( + proto.STRING, + number=1, + ) + service: str = proto.Field( + proto.STRING, + number=2, + ) + evidence_path: str = proto.Field( + proto.STRING, + number=3, + ) + + +class CloudControlAuditDetails(proto.Message): + r"""The details for a cloud control audit. + + Attributes: + cloud_control (str): + Output only. The name of the cloud control. + cloud_control_id (str): + Output only. The ID of the cloud control. + cloud_control_description (str): + Output only. The description of the cloud + control. + compliance_state (google.cloud.cloudsecuritycompliance_v1.types.ComplianceState): + Output only. The overall status of the + findings for the control. + report_summary (google.cloud.cloudsecuritycompliance_v1.types.ReportSummary): + Output only. The summary of the report. + findings (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.FindingDetails]): + Output only. The findings for the control. + """ + + cloud_control: str = proto.Field( + proto.STRING, + number=1, + ) + cloud_control_id: str = proto.Field( + proto.STRING, + number=2, + ) + cloud_control_description: str = proto.Field( + proto.STRING, + number=3, + ) + compliance_state: "ComplianceState" = proto.Field( + proto.ENUM, + number=4, + enum="ComplianceState", + ) + report_summary: "ReportSummary" = proto.Field( + proto.MESSAGE, + number=5, + message="ReportSummary", + ) + findings: MutableSequence["FindingDetails"] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message="FindingDetails", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/cm_enrollment_service.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/cm_enrollment_service.py new file mode 100644 index 000000000000..07d5d0d3983c --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/cm_enrollment_service.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import field_mask_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.cloudsecuritycompliance.v1", + manifest={ + "UpdateCmEnrollmentRequest", + "CalculateEffectiveCmEnrollmentRequest", + "CmEnrollment", + "CalculateEffectiveCmEnrollmentResponse", + "AuditConfig", + }, +) + + +class UpdateCmEnrollmentRequest(proto.Message): + r"""The request message for [UpdateCmEnrollment][]. + + Attributes: + cm_enrollment (google.cloud.cloudsecuritycompliance_v1.types.CmEnrollment): + Required. The Compliance Manager enrollment to update. The + ``name`` field is used to identify the settings that you + want to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields that you want to + update. + """ + + cm_enrollment: "CmEnrollment" = proto.Field( + proto.MESSAGE, + number=1, + message="CmEnrollment", + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class CalculateEffectiveCmEnrollmentRequest(proto.Message): + r"""The request message for [CalculateEffectiveCmEnrollment][]. + + Attributes: + name (str): + Required. The name of the Compliance Manager enrollment to + calculate. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}/cmEnrollment`` + - ``folders/{folder_id}/locations/{location}/cmEnrollment`` + - ``projects/{project_id}/locations/{location}/cmEnrollment`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CmEnrollment(proto.Message): + r"""The settings for Compliance Manager at a specific resource + scope.= + + Attributes: + name (str): + Identifier. The name of the Compliance Manager enrollment. + + Supported formats are the following: + + - ``organizations/{organization_id}/locations/{location}/cmEnrollment`` + - ``folders/{folder_id}/locations/{location}/cmEnrollment`` + - ``projects/{project_id}/locations/{location}/cmEnrollment`` + enrolled (bool): + Optional. Whether the resource is enrolled in + Compliance Manager. This setting is inherited by + all descendants. + audit_config (google.cloud.cloudsecuritycompliance_v1.types.AuditConfig): + Optional. The audit configuration for + Compliance Manager. If set at a scope, this + configuration overrides any inherited audit + configuration. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + enrolled: bool = proto.Field( + proto.BOOL, + number=2, + ) + audit_config: "AuditConfig" = proto.Field( + proto.MESSAGE, + number=3, + message="AuditConfig", + ) + + +class CalculateEffectiveCmEnrollmentResponse(proto.Message): + r"""The response message for [CalculateEffectiveCmEnrollment][]. + + Attributes: + cm_enrollment (google.cloud.cloudsecuritycompliance_v1.types.CmEnrollment): + The effective Compliance Manager enrollment + for the resource. + """ + + cm_enrollment: "CmEnrollment" = proto.Field( + proto.MESSAGE, + number=1, + message="CmEnrollment", + ) + + +class AuditConfig(proto.Message): + r"""The audit configuration for Compliance Manager. + + Attributes: + destinations (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.AuditConfig.CmEligibleDestination]): + Required. The list of destinations that can + be selected for uploading audit reports to. + """ + + class CmEligibleDestination(proto.Message): + r"""The destination details where audit reports are + uploaded. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gcs_bucket (str): + The Cloud Storage bucket where audit reports and evidences + can be uploaded. The format is ``gs://{bucket_name}``. + + This field is a member of `oneof`_ ``cm_eligible_destinations``. + """ + + gcs_bucket: str = proto.Field( + proto.STRING, + number=1, + oneof="cm_eligible_destinations", + ) + + destinations: MutableSequence[CmEligibleDestination] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=CmEligibleDestination, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/common.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/common.py index 9fe73a4697d8..eb3e5a23b1d1 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/common.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/common.py @@ -23,6 +23,7 @@ __protobuf__ = proto.module( package="google.cloud.cloudsecuritycompliance.v1", manifest={ + "RegulatoryControlResponsibilityType", "EnforcementMode", "FrameworkCategory", "CloudControlCategory", @@ -48,25 +49,45 @@ "Rule", "CELExpression", "OperationMetadata", + "ControlFamily", }, ) +class RegulatoryControlResponsibilityType(proto.Enum): + r"""The responsibility type for the regulatory control. + + Values: + REGULATORY_CONTROL_RESPONSIBILITY_TYPE_UNSPECIFIED (0): + Default value. This value is unused. + GOOGLE (1): + Google's responsibility. + CUSTOMER (2): + Your responsibility. + SHARED (3): + Shared responsibility. + """ + REGULATORY_CONTROL_RESPONSIBILITY_TYPE_UNSPECIFIED = 0 + GOOGLE = 1 + CUSTOMER = 2 + SHARED = 3 + + class EnforcementMode(proto.Enum): - r"""The enforcement mode of the cloud control. + r"""The enforcement mode for the cloud control. Values: ENFORCEMENT_MODE_UNSPECIFIED (0): Default value. This value is unused. PREVENTIVE (1): The cloud control is enforced to prevent - resource non-compliance. + non-compliance. DETECTIVE (2): The cloud control is enforced to detect - resource non-compliance. + non-compliance. AUDIT (3): - The cloud control is enforced to audit - resource non-compliance. + The cloud control is enforced to audit for + non-compliance. """ ENFORCEMENT_MODE_UNSPECIFIED = 0 PREVENTIVE = 1 @@ -75,21 +96,21 @@ class EnforcementMode(proto.Enum): class FrameworkCategory(proto.Enum): - r"""The category of the framework. + r"""The category for the framework. Values: FRAMEWORK_CATEGORY_UNSPECIFIED (0): Default value. This value is unused. INDUSTRY_DEFINED_STANDARD (1): - Standard framework + An industry-defined framework. ASSURED_WORKLOADS (2): - Assured Workloads framework + An Assured Workloads framework. DATA_SECURITY (3): - Data Security framework + A data security posture framework. GOOGLE_BEST_PRACTICES (4): - Google Best Practices framework + A Google's best practices framework. CUSTOM_FRAMEWORK (5): - User created framework. + A user-created framework. """ FRAMEWORK_CATEGORY_UNSPECIFIED = 0 INDUSTRY_DEFINED_STANDARD = 1 @@ -100,42 +121,44 @@ class FrameworkCategory(proto.Enum): class CloudControlCategory(proto.Enum): - r"""The category of the cloud control. + r"""The category for the cloud control. Values: CLOUD_CONTROL_CATEGORY_UNSPECIFIED (0): Default value. This value is unused. CC_CATEGORY_INFRASTRUCTURE (1): - Infrastructure + The infrastructure security category. CC_CATEGORY_ARTIFICIAL_INTELLIGENCE (2): - Artificial Intelligence + The artificial intelligence category. CC_CATEGORY_PHYSICAL_SECURITY (3): - Physical Security + The physical security category. CC_CATEGORY_DATA_SECURITY (4): - Data Security + The data security category. CC_CATEGORY_NETWORK_SECURITY (5): - Network Security + The network security category. CC_CATEGORY_INCIDENT_MANAGEMENT (6): - Incident Management + The incident management category. CC_CATEGORY_IDENTITY_AND_ACCESS_MANAGEMENT (7): - Identity & Access Management + The identity and access management category. CC_CATEGORY_ENCRYPTION (8): - Encryption + The encryption category. CC_CATEGORY_LOGS_MANAGEMENT_AND_INFRASTRUCTURE (9): - Logs Management & Infrastructure + The logs management and infrastructure + category. CC_CATEGORY_HR_ADMIN_AND_PROCESSES (10): - HR, Admin & Processes + The HR, admin, and processes category. CC_CATEGORY_THIRD_PARTY_AND_SUB_PROCESSOR_MANAGEMENT (11): - Third Party & Sub-Processor Management + The third-party and sub-processor management + category. CC_CATEGORY_LEGAL_AND_DISCLOSURES (12): - Legal & Disclosures + The legal and disclosures category. CC_CATEGORY_VULNERABILITY_MANAGEMENT (13): - Vulnerability Management + The vulnerability management category. CC_CATEGORY_PRIVACY (14): - Privacy + The privacy category. CC_CATEGORY_BCDR (15): - BCDR (Business Continuity and Disaster - Recovery) + The business continuity and disaster recovery + (BCDR) category. """ CLOUD_CONTROL_CATEGORY_UNSPECIFIED = 0 CC_CATEGORY_INFRASTRUCTURE = 1 @@ -156,7 +179,7 @@ class CloudControlCategory(proto.Enum): class CloudProvider(proto.Enum): - r"""The cloud platform. + r"""The cloud provider that's associated with the cloud control. Values: CLOUD_PROVIDER_UNSPECIFIED (0): @@ -179,50 +202,38 @@ class Severity(proto.Enum): Values: SEVERITY_UNSPECIFIED (0): - This value is used for findings when a source - doesn't write a severity value. + Default value. This value is unused. CRITICAL (1): - Vulnerability: - - A critical vulnerability is easily discoverable - by an external actor, exploitable, and results - in the direct ability to execute arbitrary code, - exfiltrate data, and otherwise gain additional - access and privileges to cloud resources and - workloads. Examples include publicly accessible - unprotected user data and public SSH access with - weak or no passwords. - - Threat: - - Indicates a threat that is able to access, + A critical vulnerability is easily + discoverable by an external actor, exploitable, + and results in the direct ability to execute + arbitrary code, exfiltrate data, and otherwise + gain additional access and privileges to cloud + resources and workloads. Examples include + publicly accessible unprotected user data and + public SSH access with weak or no passwords. + + A critical threat is a threat that can access, modify, or delete data or execute unauthorized code within existing resources. HIGH (2): - Vulnerability: - - A high risk vulnerability can be easily + A high-risk vulnerability can be easily discovered and exploited in combination with - other vulnerabilities in order to gain direct - access and the ability to execute arbitrary - code, exfiltrate data, and otherwise gain - additional access and privileges to cloud - resources and workloads. An example is a - database with weak or no passwords that is only - accessible internally. This database could - easily be compromised by an actor that had - access to the internal network. - - Threat: - - Indicates a threat that is able to create new - computational resources in an environment but - not able to access data or execute code in + other vulnerabilities to gain direct access and + the ability to execute arbitrary code, + exfiltrate data, and otherwise gain additional + access and privileges to cloud resources and + workloads. An example is a database with weak or + no passwords that is only accessible internally. + This database could easily be compromised by an + actor that had access to the internal network. + + A high-risk threat is a threat that can create + new computational resources in an environment + but can't access data or execute code in existing resources. MEDIUM (3): - Vulnerability: - - A medium risk vulnerability could be used by an + A medium-risk vulnerability can be used by an actor to gain access to resources or privileges that enable them to eventually (through multiple steps or a complex exploit) gain access and the @@ -234,15 +245,11 @@ class Severity(proto.Enum): manipulate a project the service account was not intended to. - Threat: - - Indicates a threat that is able to cause - operational impact but may not access data or - execute unauthorized code. + A medium-risk threat can cause operational + impact but might not access data or execute + unauthorized code. LOW (4): - Vulnerability: - - A low risk vulnerability hampers a security + A low-risk vulnerability hampers a security organization's ability to detect vulnerabilities or active threats in their deployment, or prevents the root cause investigation of @@ -250,10 +257,8 @@ class Severity(proto.Enum): logs being disabled for resource configurations and access. - Threat: - - Indicates a threat that has obtained minimal - access to an environment but is not able to + A low-risk threat is a threat that has obtained + minimal access to an environment but can't access data, execute code, or create resources. """ SEVERITY_UNSPECIFIED = 0 @@ -270,11 +275,13 @@ class RuleActionType(proto.Enum): RULE_ACTION_TYPE_UNSPECIFIED (0): Default value. This value is unused. RULE_ACTION_TYPE_PREVENTIVE (1): - Preventative action type. + The rule is intended to prevent + non-compliance. RULE_ACTION_TYPE_DETECTIVE (2): - Detective action type. + The rule is intended to detect + non-compliance. RULE_ACTION_TYPE_AUDIT (3): - Audit action type. + The rule is intended to audit non-compliance. """ RULE_ACTION_TYPE_UNSPECIFIED = 0 RULE_ACTION_TYPE_PREVENTIVE = 1 @@ -283,20 +290,22 @@ class RuleActionType(proto.Enum): class TargetResourceType(proto.Enum): - r"""TargetResourceType represents the type of resource that a - control or framework can be applied to. + r"""The type of resource that a control or framework can be + applied to. Values: TARGET_RESOURCE_TYPE_UNSPECIFIED (0): Default value. This value is unused. TARGET_RESOURCE_CRM_TYPE_ORG (1): - Target resource is an Organization. + The target resource is a Google Cloud + organization. TARGET_RESOURCE_CRM_TYPE_FOLDER (2): - Target resource is a Folder. + The target resource is a folder. TARGET_RESOURCE_CRM_TYPE_PROJECT (3): - Target resource is a Project. + The target resource is a project. TARGET_RESOURCE_TYPE_APPLICATION (4): - Target resource is an Application. + The target resource is an application in App + Hub. """ TARGET_RESOURCE_TYPE_UNSPECIFIED = 0 TARGET_RESOURCE_CRM_TYPE_ORG = 1 @@ -306,56 +315,57 @@ class TargetResourceType(proto.Enum): class Framework(proto.Message): - r"""A Framework is a collection of CloudControls to address - security and compliance requirements. Frameworks can be used for - prevention, detection, and auditing. They can be either - built-in, industry-standard frameworks provided by GCP/AZURE/AWS - (e.g., NIST, FedRAMP) or custom frameworks created by users. + r"""A framework is a collection of cloud controls and regulatory + controls that represent security best practices or + industry-defined standards such as FedRAMP or NIST. Attributes: name (str): - Required. Identifier. The name of the framework. Format: - organizations/{organization}/locations/{location}/frameworks/{framework_id} + Required. Identifier. The name of the framework, in the + format + ``organizations/{organization}/locations/{location}/frameworks/{framework_id}``. + The only supported location is ``global``. major_revision_id (int): - Output only. Major revision of the framework - incremented in ascending order. + Output only. The major version of the + framework, which is incremented in ascending + order. display_name (str): - Optional. Display name of the framework. The - maximum length is 200 characters. + Optional. The friendly name of the framework. + The maximum length is 200 characters. description (str): Optional. The description of the framework. The maximum length is 2000 characters. type_ (google.cloud.cloudsecuritycompliance_v1.types.Framework.FrameworkType): - Output only. The type of the framework. The default is - TYPE_CUSTOM. + Output only. The type of framework. cloud_control_details (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudControlDetails]): - Optional. The details of the cloud controls + Optional. The cloud control details that are directly added without any grouping in the framework. category (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.FrameworkCategory]): Optional. The category of the framework. supported_cloud_providers (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudProvider]): - Output only. cloud providers supported + Output only. The cloud providers that are + supported by the framework. supported_target_resource_types (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.TargetResourceType]): - Output only. target resource types supported - by the Framework. + Output only. The target resource types that + are supported by the framework. supported_enforcement_modes (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.EnforcementMode]): Output only. The supported enforcement modes of the framework. """ class FrameworkType(proto.Enum): - r"""The type of the framework. + r"""The type of framework. Values: FRAMEWORK_TYPE_UNSPECIFIED (0): Default value. This value is unused. BUILT_IN (1): - The framework is a built-in framework if it - is created and managed by GCP. + A framework that's provided and managed by + Google. CUSTOM (2): - The framework is a custom framework if it is - created and managed by the user. + A framework that's created and managed by + you. """ FRAMEWORK_TYPE_UNSPECIFIED = 0 BUILT_IN = 1 @@ -414,22 +424,22 @@ class FrameworkType(proto.Enum): class CloudControlDetails(proto.Message): - r"""CloudControlDetails contains the details of a CloudControl. + r"""The details of a cloud control. Attributes: name (str): - Required. The name of the CloudControl in the - format: - “organizations/{organization}/locations/{location}/ - cloudControls/{cloud-control}” + Required. The name of the cloud control, in the format + ``organizations/{organization}/locations/{location}/cloudControls/{cloud-control}``. + The only supported location is ``global``. major_revision_id (int): - Required. Major revision of cloudcontrol + Required. The major version of the cloud + control. parameters (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.Parameter]): - Optional. Parameters is a key-value pair that - is required by the CloudControl. The - specification of these parameters will be - present in cloudcontrol.Eg: { "name": - "location","value": "us-west-1"}. + Optional. Parameters are key-value pairs that let you + provide your custom location requirements, environment + requirements, or other settings that are relevant to the + cloud control. An example parameter is + ``{"name": "location","value": "us-west-1"}``. """ name: str = proto.Field( @@ -448,19 +458,22 @@ class CloudControlDetails(proto.Message): class FrameworkReference(proto.Message): - r"""FrameworkReference contains the reference of a framework. + r"""The reference of a framework, in the format + ``organizations/{organization}/locations/{location}/frameworks/{framework}``. + The only supported location is ``global``. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: framework (str): - Required. In the format: - - organizations/{org}/locations/{location}/frameworks/{framework} + Required. The major version of the framework. + If not specified, the version corresponds to the + latest version of the framework. major_revision_id (int): - Optional. Major revision id of the framework. - If not specified, corresponds to the latest - revision of the framework. + Optional. The major version of the framework. + If not specified, the version corresponds to the + latest version of the framework. This field is a member of `oneof`_ ``_major_revision_id``. """ @@ -477,13 +490,15 @@ class FrameworkReference(proto.Message): class Parameter(proto.Message): - r"""Parameters is a key-value pair. + r"""Parameters are key-value pairs that let you provide your + custom location requirements, environment requirements, or other + settings that are relevant to the cloud control. Attributes: name (str): - Required. The name of the parameter. + Required. The name or key of the parameter. parameter_value (google.cloud.cloudsecuritycompliance_v1.types.ParamValue): - Required. The value of the parameter + Required. The value of the parameter. """ name: str = proto.Field( @@ -498,64 +513,80 @@ class Parameter(proto.Message): class CloudControl(proto.Message): - r"""A CloudControl is the fundamental unit encapsulating the rules to - meet a specific security or compliance intent. It can contain - various rule types (like Organization Policies, CEL expressions, - etc.) enabling different enforcement modes (Preventive, Detective, - Audit). CloudControls are often parameterized for reusability and - can be either BUILT_IN (provided by Google) or CUSTOM (defined by - the user). + r"""A cloud control is a set of rules and associated metadata + that you can use to define your organization's security or + compliance intent. Attributes: name (str): - Required. Identifier. The resource name of the cloud - control. Format: - organizations/{organization}/locations/{location}/cloudControls/{cloud_control_id} + Required. Identifier. The name of the cloud control, in the + format + ``organizations/{organization}/locations/{location}/cloudControls/{cloud_control_id}``. + The only supported location is ``global``. major_revision_id (int): - Output only. Major revision of the cloud - control incremented in ascending order. + Output only. The major version of the cloud + control, which is incremented in ascending + order. description (str): Optional. A description of the cloud control. The maximum length is 2000 characters. display_name (str): - Optional. The display name of the cloud + Optional. The friendly name of the cloud control. The maximum length is 200 characters. supported_enforcement_modes (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.EnforcementMode]): - Output only. The supported enforcement mode - of the cloud control. Default is DETECTIVE. + Output only. The supported enforcement modes + for the cloud control. parameter_spec (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.ParameterSpec]): - Optional. The parameter spec of the cloud - control. + Optional. The parameter specifications for + the cloud control. rules (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.Rule]): - Optional. The Policy to be enforced to - prevent/detect resource non-compliance. + Optional. The rules that you can enforce to + meet your security or compliance intent. severity (google.cloud.cloudsecuritycompliance_v1.types.Severity): - Optional. The severity of findings generated - by the cloud control. + Optional. The severity of the findings that + are generated by the cloud control. finding_category (str): - Optional. The finding_category of the cloud control. The - maximum length is 255 characters. + Optional. The finding category for the cloud + control findings. The maximum length is 255 + characters. supported_cloud_providers (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudProvider]): - Optional. cloud providers supported + Optional. The supported cloud providers. related_frameworks (MutableSequence[str]): - Output only. The Frameworks that include this - CloudControl + Output only. The frameworks that include this + cloud control. remediation_steps (str): - Optional. The remediation steps for the - findings generated by the cloud control. The - maximum length is 400 characters. + Optional. The remediation steps for the cloud + control findings. The maximum length is 400 + characters. categories (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudControlCategory]): - Optional. The categories of the cloud + Optional. The categories for the cloud control. create_time (google.protobuf.timestamp_pb2.Timestamp): - Output only. The last updated time of the cloud control. The - create_time is used because a new CC is created whenever we - update an existing CC. + Output only. The time that the cloud control was last + updated. ``create_time`` is used because a new cloud control + is created whenever an existing cloud control is updated. supported_target_resource_types (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.TargetResourceType]): - Optional. target resource types supported by - the CloudControl. + Optional. The target resource types that are + supported by the cloud control. """ + class Type(proto.Enum): + r"""The type of cloud control. + + Values: + TYPE_UNSPECIFIED (0): + Default value. This value is unused. + CUSTOM (1): + A cloud control that's created and managed by + you. + BUILT_IN (2): + A cloud control that's provided and managed + by Google. + """ + TYPE_UNSPECIFIED = 0 + CUSTOM = 1 + BUILT_IN = 2 + name: str = proto.Field( proto.STRING, number=1, @@ -631,48 +662,50 @@ class CloudControl(proto.Message): class ParameterSpec(proto.Message): - r"""A parameter spec of the cloud control. + r"""The parameter specification for the cloud control. Attributes: name (str): Required. The name of the parameter. display_name (str): - Optional. The display name of the parameter. + Optional. The friendly name of the parameter. The maximum length is 200 characters. description (str): Optional. The description of the parameter. The maximum length is 2000 characters. is_required (bool): - Required. if the parameter is required + Required. Whether the parameter is required. value_type (google.cloud.cloudsecuritycompliance_v1.types.ParameterSpec.ValueType): - Required. Parameter value type. + Required. The parameter value type. default_value (google.cloud.cloudsecuritycompliance_v1.types.ParamValue): Optional. The default value of the parameter. substitution_rules (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.ParameterSubstitutionRule]): - Optional. List of parameter substitutions. + Optional. The list of parameter + substitutions. sub_parameters (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.ParameterSpec]): - Optional. ParameterSpec for oneof attributes. + Optional. The parameter specification for ``oneOf`` + attributes. validation (google.cloud.cloudsecuritycompliance_v1.types.Validation): - Optional. The allowed set of values for the + Optional. The permitted set of values for the parameter. """ class ValueType(proto.Enum): - r"""The type of the parameter value. + r"""The type of parameter value. Values: VALUE_TYPE_UNSPECIFIED (0): Default value. This value is unused. STRING (3): - String value. + A string value. BOOLEAN (4): - Boolean value. + A boolean value. STRINGLIST (5): - String list value. + A string list value. NUMBER (6): - Numeric value. + A numeric value. ONEOF (7): - OneOf value. + A oneOf value. """ VALUE_TYPE_UNSPECIFIED = 0 STRING = 3 @@ -727,7 +760,7 @@ class ValueType(proto.Enum): class Validation(proto.Message): - r"""Validation of the parameter. + r"""The validation of the parameter. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -738,15 +771,16 @@ class Validation(proto.Message): Attributes: allowed_values (google.cloud.cloudsecuritycompliance_v1.types.AllowedValues): - Allowed set of values for the parameter. + The permitted set of values for the + parameter. This field is a member of `oneof`_ ``constraint``. int_range (google.cloud.cloudsecuritycompliance_v1.types.IntRange): - Allowed range for numeric parameters. + The permitted range for numeric parameters. This field is a member of `oneof`_ ``constraint``. regexp_pattern (google.cloud.cloudsecuritycompliance_v1.types.RegexpPattern): - Regular expression for string parameters. + The regular expression for string parameters. This field is a member of `oneof`_ ``constraint``. """ @@ -772,11 +806,11 @@ class Validation(proto.Message): class AllowedValues(proto.Message): - r"""Allowed set of values for the parameter. + r"""The allowed set of values for the parameter. Attributes: values (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.ParamValue]): - Required. List of allowed values for the + Required. The list of allowed values for the parameter. """ @@ -788,12 +822,13 @@ class AllowedValues(proto.Message): class RegexpPattern(proto.Message): - r"""Regular Expression Validator for parameter values. + r"""The regular expression (regex) validator for parameter + values. Attributes: pattern (str): - Required. Regex Pattern to match the value(s) - of parameter. + Required. The regex pattern to match the + values of the parameter with. """ pattern: str = proto.Field( @@ -803,14 +838,14 @@ class RegexpPattern(proto.Message): class IntRange(proto.Message): - r"""Number range for number parameters. + r"""The number range for number parameters. Attributes: min_ (int): - Required. Minimum allowed value for the + Required. The minimum permitted value for the numeric parameter (inclusive). max_ (int): - Required. Maximum allowed value for the + Required. The maximum permitted value for the numeric parameter (inclusive). """ @@ -825,7 +860,7 @@ class IntRange(proto.Message): class StringList(proto.Message): - r"""A list of strings. + r"""A list of strings for the parameter value. Attributes: values (MutableSequence[str]): @@ -839,7 +874,7 @@ class StringList(proto.Message): class ParamValue(proto.Message): - r"""Possible parameter value types. + r"""The possible parameter value types. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -850,23 +885,23 @@ class ParamValue(proto.Message): Attributes: string_value (str): - Represents a string value. + A string value. This field is a member of `oneof`_ ``kind``. bool_value (bool): - Represents a boolean value. + A boolean value. This field is a member of `oneof`_ ``kind``. string_list_value (google.cloud.cloudsecuritycompliance_v1.types.StringList): - Represents a repeated string. + A repeated string. This field is a member of `oneof`_ ``kind``. number_value (float): - Represents a double value. + A double value. This field is a member of `oneof`_ ``kind``. oneof_value (google.cloud.cloudsecuritycompliance_v1.types.Parameter): - Represents sub-parameter values. + Sub-parameter values. This field is a member of `oneof`_ ``kind``. """ @@ -901,7 +936,7 @@ class ParamValue(proto.Message): class ParameterSubstitutionRule(proto.Message): - r"""Parameter substitution rules. + r"""The parameter substitution rules. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -912,11 +947,11 @@ class ParameterSubstitutionRule(proto.Message): Attributes: placeholder_substitution_rule (google.cloud.cloudsecuritycompliance_v1.types.PlaceholderSubstitutionRule): - Placeholder substitution rule. + The placeholder substitution rule. This field is a member of `oneof`_ ``substitution_type``. attribute_substitution_rule (google.cloud.cloudsecuritycompliance_v1.types.AttributeSubstitutionRule): - Attribute substitution rule. + The attribute substitution rule. This field is a member of `oneof`_ ``substitution_type``. """ @@ -936,12 +971,13 @@ class ParameterSubstitutionRule(proto.Message): class AttributeSubstitutionRule(proto.Message): - r"""Attribute at the given path is substituted entirely. + r"""The attribute at the given path that's substituted entirely. Attributes: attribute (str): - Fully qualified proto attribute path (in dot notation). - Example: rules[0].cel_expression.resource_types_values + The fully qualified proto attribute path, in dot notation. + For example: + ``rules[0].cel_expression.resource_types_values`` """ attribute: str = proto.Field( @@ -951,12 +987,12 @@ class AttributeSubstitutionRule(proto.Message): class PlaceholderSubstitutionRule(proto.Message): - r"""Placeholder is substituted in the rendered string. + r"""The placeholder that's substituted in the rendered string. Attributes: attribute (str): - Fully qualified proto attribute path (e.g., - dot notation) + The fully qualified proto attribute path, in + dot notation. """ attribute: str = proto.Field( @@ -966,21 +1002,22 @@ class PlaceholderSubstitutionRule(proto.Message): class Rule(proto.Message): - r"""A rule of the cloud control. + r"""A rule in the cloud control. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: cel_expression (google.cloud.cloudsecuritycompliance_v1.types.CELExpression): - Logic expression in CEL language. + The rule's logic expression in Common + Expression Language (CEL). This field is a member of `oneof`_ ``implementation``. description (str): - Optional. Description of the Rule. The - maximum length is 2000 characters. + Optional. The rule description. The maximum + length is 2000 characters. rule_action_types (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.RuleActionType]): - Required. The functionality enabled by the - Rule. + Required. The functionality that's enabled by + the rule. """ cel_expression: "CELExpression" = proto.Field( @@ -1001,8 +1038,8 @@ class Rule(proto.Message): class CELExpression(proto.Message): - r"""A `CEL - expression `__. + r"""A Common Expression Language (CEL) expression that's used to + create a rule. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -1010,15 +1047,15 @@ class CELExpression(proto.Message): Attributes: resource_types_values (google.cloud.cloudsecuritycompliance_v1.types.StringList): The resource instance types on which this expression is - defined. Format will be of the form : - ``/`` Example: - ``compute.googleapis.com/Instance``. + defined. The format is ``/``. For + example: ``compute.googleapis.com/Instance`` This field is a member of `oneof`_ ``criteria``. expression (str): - Required. Logic expression in CEL language. - The max length of the condition is 1000 - characters. + Required. The logical expression in CEL. The maximum length + of the condition is 1000 characters. For more information, + see `CEL + expression `__. """ resource_types_values: "StringList" = proto.Field( @@ -1034,7 +1071,7 @@ class CELExpression(proto.Message): class OperationMetadata(proto.Message): - r"""Represents the metadata of the long-running operation. + r"""The metadata for the long-running operation. Attributes: create_time (google.protobuf.timestamp_pb2.Timestamp): @@ -1044,23 +1081,24 @@ class OperationMetadata(proto.Message): Output only. The time the operation finished running. target (str): - Output only. Server-defined resource path for - the target of the operation. + Output only. The server-defined resource path + for the target of the operation. verb (str): - Output only. Name of the verb executed by the - operation. + Output only. The name of the verb that was + executed by the operation. status_message (str): - Output only. Human-readable status of the + Output only. The human-readable status of the operation, if any. requested_cancellation (bool): - Output only. Identifies whether the user has requested - cancellation of the operation. Operations that have been - cancelled successfully have [Operation.error][] value with a - [google.rpc.Status.code][google.rpc.Status.code] of 1, - corresponding to ``Code.CANCELLED``. + Output only. Identifies whether the user has requested that + the operation be cancelled. If an operation was cancelled + successfully, then the field + [google.longrunning.Operation.error][google.longrunning.Operation.error] + contains the value + [google.rpc.Code.CANCELLED][google.rpc.Code.CANCELLED]. api_version (str): - Output only. API version used to start the - operation. + Output only. The API version that was used to + start the operation. """ create_time: timestamp_pb2.Timestamp = proto.Field( @@ -1095,4 +1133,26 @@ class OperationMetadata(proto.Message): ) +class ControlFamily(proto.Message): + r"""The regulatory family of the control. + + Attributes: + family_id (str): + The identifier for the regulatory control + family. + display_name (str): + The friendly name for the regulatory control + family. + """ + + family_id: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/config.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/config.py index ea92b040f0f1..398ae17b8c99 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/config.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/config.py @@ -42,13 +42,13 @@ class ListFrameworksRequest(proto.Message): - r"""Request message for listing Frameworks. + r"""Request message for [ListFrameworks][]. Attributes: parent (str): Required. The parent resource name, in the format - ``organizations/{organization}/locations/{location}``. Only - global location is supported. + ``organizations/{organization}/locations/{location}``. The + only supported location is ``global``. page_size (int): Optional. The maximum number of frameworks to return. The default value is ``500``. @@ -76,12 +76,12 @@ class ListFrameworksRequest(proto.Message): class ListFrameworksResponse(proto.Message): - r"""Response message for listing Frameworks. - Contains a paginated list of Framework resources. + r"""The response message for [ListFrameworks][]. Returns a paginated + list of Framework resources. Attributes: frameworks (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.Framework]): - The list of Framework resources. + The list of framework resources. next_page_token (str): A pagination token. To retrieve the next page of results, call the method again with this @@ -104,15 +104,17 @@ def raw_page(self): class GetFrameworkRequest(proto.Message): - r"""Request message for getting a Framework. + r"""The request message for [GetFramework][]. Attributes: name (str): - Required. The name of the framework to retrieve. Format: - organizations/{organization}/locations/{location}/frameworks/{framework_id} + Required. The name of the framework to retrieve, in the + format + ``organizations/{organization}/locations/{location}/frameworks/{framework_id}`` + The only supported location is ``global``. major_revision_id (int): - Optional. The Framework major version to retrieve. If not - specified, the most recently updated revision_id is + Optional. The framework major version to retrieve. If not + specified, the most recently updated ``revision_id`` is retrieved. """ @@ -127,19 +129,20 @@ class GetFrameworkRequest(proto.Message): class CreateFrameworkRequest(proto.Message): - r"""Request message for creating a Framework + r"""The request message for [CreateFramework][]. Attributes: parent (str): Required. The parent resource name, in the format - ``organizations/{organization}/locations/{location}``. + ``organizations/{organization}/locations/{location}``. The + only supported location is ``global``. framework_id (str): - Required. ID of the framework. - This is not the full name of the framework. - This is the last part of the full name of the - framework. + Required. The identifier (ID) of the + framework. The ID is not the full name of the + framework; it's the last part of the full name + of the framework. framework (google.cloud.cloudsecuritycompliance_v1.types.Framework): - Required. The resource being created + Required. The resource being created. """ parent: str = proto.Field( @@ -158,18 +161,18 @@ class CreateFrameworkRequest(proto.Message): class UpdateFrameworkRequest(proto.Message): - r"""Request message for updating a Framework. + r"""The request message for [UpdateFramework][]. Attributes: update_mask (google.protobuf.field_mask_pb2.FieldMask): - Optional. Field mask is used to specify the fields to be - overwritten in the Framework resource by the update. The - fields specified in the update_mask are relative to the - resource, not the full request. A field will be overwritten - if it is in the mask. If the user does not provide a mask - then all fields present in the request will be overwritten. + Optional. A field mask is used to specify the fields to be + overwritten in the framework resource by the update. The + fields specified in the ``update_mask`` are relative to the + resource, not the full request. A field is overwritten if it + is in the mask. If you don't provide a mask then all fields + present in the request will be overwritten. framework (google.cloud.cloudsecuritycompliance_v1.types.Framework): - Required. The resource being updated + Required. The resource that is being updated. major_revision_id (int): Optional. The major version ID of the framework to update. @@ -192,12 +195,13 @@ class UpdateFrameworkRequest(proto.Message): class DeleteFrameworkRequest(proto.Message): - r"""Request message for deleting a Framework. + r"""Request message for [DeleteFramework][]. Attributes: name (str): - Required. Name of the resource, in the format + Required. The name of the resource, in the format ``organizations/{organization}/locations/{location}/frameworks/{framework}``. + The only supported location is ``global``. """ name: str = proto.Field( @@ -207,26 +211,27 @@ class DeleteFrameworkRequest(proto.Message): class ListCloudControlsRequest(proto.Message): - r"""Request message for listing CloudControls. + r"""Request message for [ListCloudControls][]. Attributes: parent (str): Required. The parent resource name, in the format - ``organizations/{organization}/locations/{location}``. + ``organizations/{organization}/locations/{location}``. The + only supported location is ``global``. page_size (int): - Optional. The maximum number of CloudControls to return. The - default value is ``500``. + Optional. The maximum number of cloud controls to return. + The default value is ``500``. If you exceed the maximum value of ``1000``, then the service uses the maximum value. page_token (str): - Optional. A pagination token returned from a - previous request to list CloudControls. Provide - this token to retrieve the next page of results. + Optional. A pagination token that's returned from a previous + request to list cloud controls. Provide this token to + retrieve the next page of results. - When paginating, parent provided to - ListCloudControls request must match the call - that provided the page token. + When paginating, the parent that you provide to the + [ListCloudControls][google.cloud.cloudsecuritycompliance.v1.Config.ListCloudControls] + request must match the call that provided the page token. """ parent: str = proto.Field( @@ -244,7 +249,7 @@ class ListCloudControlsRequest(proto.Message): class ListCloudControlsResponse(proto.Message): - r"""Response message for ListCloudControls. + r"""The response message for [ListCloudControls][]. Attributes: cloud_controls (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudControl]): @@ -271,34 +276,45 @@ def raw_page(self): class GetCloudControlRequest(proto.Message): - r"""Request message for getting a CloudControl. + r"""The request message for [GetCloudControl][]. Attributes: name (str): - Required. The name of the cloudcontrol to retrieve in the - format: - organizations/{organization}/locations/{location}/cloudControls/{cloud_control} + Required. The name of the cloud control to retrieve, in the + format + ``organizations/{organization}/locations/{location}/cloudControls/{cloud_control}``. + The only supported location is ``global``. + major_revision_id (int): + Optional. The major version of the cloud control to + retrieve. If not specified, the most recently updated + ``revision_id`` is retrieved. """ name: str = proto.Field( proto.STRING, number=1, ) + major_revision_id: int = proto.Field( + proto.INT64, + number=2, + ) class CreateCloudControlRequest(proto.Message): - r"""Request message for creating a CloudControl + r"""The request message for [CreateCloudControl][]. Attributes: parent (str): Required. The parent resource name, in the format - ``organizations/{organization}/locations/{location}``. + ``organizations/{organization}/locations/{location}``. The + only supported location is ``global``. cloud_control_id (str): - Required. ID of the CloudControl. This is the last segment - of the CloudControl resource name. Format: + Required. The identifier for the cloud control, which is the + last segment of the cloud control name. The format is ``^[a-zA-Z][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$``. cloud_control (google.cloud.cloudsecuritycompliance_v1.types.CloudControl): - Required. The resource being created + Required. The cloud control that's being + created. """ parent: str = proto.Field( @@ -317,25 +333,27 @@ class CreateCloudControlRequest(proto.Message): class UpdateCloudControlRequest(proto.Message): - r"""Request message for UpdateCloudControl. + r"""The request message for [UpdateCloudControl][]. Attributes: update_mask (google.protobuf.field_mask_pb2.FieldMask): - Optional. Field mask is used to specify the fields to be - overwritten in the CloudControl resource by the update. The - fields specified in the update_mask are relative to the - resource, not the full request. A field will be overwritten - if it is in the mask. If the user does not provide a mask - then all fields present in the request will be overwritten. - The fields that can be updated are: - - 1. Display_name - 2. Description - 3. Parameters - 4. Rules - 5. ParameterSpec. + Optional. Use a field mask to specify the fields to be + overwritten in the cloud control during the update. The + fields that you specify in the ``update_mask`` are relative + to the cloud control, not the full request. A field is + overwritten if it is in the mask. If you don't provide a + mask, all fields in the request are updated. + + You can update the following fields: + + - Display name + - Description + - Parameters + - Rules + - Parameter specification cloud_control (google.cloud.cloudsecuritycompliance_v1.types.CloudControl): - Required. The resource being updated + Required. The cloud control that you're + updating. """ update_mask: field_mask_pb2.FieldMask = proto.Field( @@ -351,12 +369,14 @@ class UpdateCloudControlRequest(proto.Message): class DeleteCloudControlRequest(proto.Message): - r"""Request message for deleting a CloudControl. + r"""The request message for [DeleteCloudControl][]. Attributes: name (str): - Required. Name of the resource, in the format + Required. The name of the cloud control to delete, in the + format ``organizations/{organization}/locations/{location}/CloudControls/{CloudControl}``. + The only supported location is ``global``. """ name: str = proto.Field( diff --git a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/deployment.py b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/deployment.py index 64176f077889..7a3dbc283439 100644 --- a/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/deployment.py +++ b/packages/google-cloud-cloudsecuritycompliance/google/cloud/cloudsecuritycompliance_v1/types/deployment.py @@ -48,34 +48,33 @@ class DeploymentState(proto.Enum): - r"""DeploymentState represents the state of the Deployment - resource. + r"""The state of the deployment resource. Values: DEPLOYMENT_STATE_UNSPECIFIED (0): - Unspecified. Invalid state. + Default value. This value is unused. DEPLOYMENT_STATE_VALIDATING (1): Validating the deployment. DEPLOYMENT_STATE_CREATING (2): - Deployment is in CREATING state. + Deployment is being created. DEPLOYMENT_STATE_DELETING (3): - Deployment is in DELETING state. + Deployment is being deleted. DEPLOYMENT_STATE_FAILED (4): Deployment has failed. All the changes made - by the deployment have been successfully rolled - back. A deployment in the FAILED state can be - retried or deleted. + by the deployment were successfully rolled back. + You can retry or delete a deployment that's in + this state. DEPLOYMENT_STATE_READY (5): Deployment is successful and ready to use. DEPLOYMENT_STATE_PARTIALLY_DEPLOYED (6): Deployment is partially deployed. All the - Cloud Controls were not deployed successfully. - Retrying the operation will resume from the - first failed step. + cloud controls weren't deployed successfully. + Retrying the operation resumes from the first + failed step. DEPLOYMENT_STATE_PARTIALLY_DELETED (7): Deployment is partially deleted. All the - Cloud Control Deployments were not deleted - successfully. Retrying the operation will resume + cloud control deployments weren't deleted + successfully. Retrying the operation resumes from the first failed step. """ DEPLOYMENT_STATE_UNSPECIFIED = 0 @@ -89,42 +88,42 @@ class DeploymentState(proto.Enum): class FrameworkDeployment(proto.Message): - r"""FrameworkDeployment represents deployment of a Framework on a - target resource. Supported target resources are - organizations/{organization}, folders/{folder}, and - projects/{project}. + r"""Framework deployments represent the assignment of a framework + to a target resource. Supported target resources are + organizations, folders, and projects. Attributes: name (str): - Identifier. FrameworkDeployment name in the following - format: - organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id} + Identifier. The name of the framework deployment, in the + format + ``organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id}``. + The only supported location is ``global``. target_resource_config (google.cloud.cloudsecuritycompliance_v1.types.TargetResourceConfig): Required. The details of the target resource - on which the Framework is to be deployed. It can - either be an existing target resource or a new - target resource to be created. + that you want to deploy the framework to. You + can specify an existing resource, or create a + new one. computed_target_resource (str): - Output only. The resource on which the - Framework is deployed based on the provided - TargetResourceConfig in the following format: + Output only. The target resource to deploy the framework to, + in one the following formats: - organizations/{organization}, folders/{folder} - or projects/{project} + - ``organizations/{organizationID}`` + - ``folders/{folderID}`` + - ``projects/{projectID}`` framework (google.cloud.cloudsecuritycompliance_v1.types.FrameworkReference): - Required. Reference to the framework to be - deployed. + Required. A reference to the framework that + you're deploying. description (str): - Optional. User provided description of the - Framework deployment + Optional. A user-provided description of the + framework deployment. cloud_control_metadata (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudControlMetadata]): - Required. Deployment mode and parameters for - each of the Cloud Controls in the framework. - Every Cloud Control in the framework must have a - CloudControlMetadata. + Required. The deployment mode and parameters + for each of the cloud controls in the framework. + Every cloud control in the framework includes + metadata. deployment_state (google.cloud.cloudsecuritycompliance_v1.types.DeploymentState): - Output only. State of the Framework - Deployment + Output only. The state for the framework + deployment. create_time (google.protobuf.timestamp_pb2.Timestamp): Output only. The time at which the resource was created. @@ -134,27 +133,34 @@ class FrameworkDeployment(proto.Message): etag (str): Optional. To prevent concurrent updates from overwriting each other, always provide the ``etag`` when you update a - FrameworkDeployment. You can also provide the ``etag`` when - you delete a FrameworkDeployment, to help ensure that you're - deleting the intended version of the FrameworkDeployment. + framework deployment. You can also provide the ``etag`` when + you delete a framework deployment, to help ensure that + you're deleting the intended version of the framework + deployment. target_resource_display_name (str): Output only. The display name of the target resource. cloud_control_deployment_references (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudControlDeploymentReference]): Output only. The references to the cloud control - deployments. It has all the CloudControlDeployments which - are either directly added in the framework or through a - CloudControlGroup. Example: If a framework deployment - deploys two cloud controls, cc-deployment-1 and - cc-deployment-2, then the - cloud_control_deployment_references will be: { - cloud_control_deployment_reference: { - cloud_control_deployment: - "organizations/{organization}/locations/{location}/cloudControlDeployments/cc-deployment-1" - }, cloud_control_deployment_reference: { - cloud_control_deployment: - "organizations/{organization}/locations/{location}/cloudControlDeployments/cc-deployment-2" - } + deployments. The reference includes all the cloud control + deployments that are in the framework or in a cloud control + group. + + For example, if a framework deployment deploys two cloud + controls, ``cc-deployment-1`` and ``cc-deployment-2``, then + the references are: + + :: + + { + cloud_control_deployment_reference: { + cloud_control_deployment: + "organizations/{organization}/locations/{location}/cloudControlDeployments/cc-deployment-1" + }, + cloud_control_deployment_reference: { + cloud_control_deployment: + "organizations/{organization}/locations/{location}/cloudControlDeployments/cc-deployment-2" + } """ name: str = proto.Field( @@ -219,58 +225,58 @@ class FrameworkDeployment(proto.Message): class CloudControlDeployment(proto.Message): - r"""CloudControlDeployment represents deployment of a - CloudControl on a target resource. Supported target resources - are organizations/{organization}, folders/{folder}, and - projects/{project}. + r"""A cloud control deployment represents the deployment of a particular + cloud control on a target resource. Supported target resources are + ``organizations/{organizationID}``, ``folders/{folderID}``, and + ``projects/{projectID}``. Attributes: name (str): - Identifier. CloudControlDeployment name in the following - format: - organizations/{organization}/locations/{location}/cloudControlDeployments/{cloud_control_deployment_id} + Identifier. The name for the cloud control deployment, in + the format + ``organizations/{organization}/locations/{location}/cloudControlDeployments/{cloud_control_deployment_id}``. + The only supported location is ``global``. target_resource_config (google.cloud.cloudsecuritycompliance_v1.types.TargetResourceConfig): Required. The details of the target resource - on which the CloudControl is to be deployed. It - can either be an existing target resource or a - new target resource to be created. + that the cloud control is deployed You can use + an existing target resource or create a new + target. target_resource (str): - Output only. The resource on which the - CloudControl is deployed based on the provided - TargetResourceConfig in the following format: + Output only. The resource that the cloud control is deployed + on, in one of the following formats: - organizations/{organization}, folders/{folder} - or projects/{project}. + - ``organizations/{organizationID}`` + - ``folders/{folderID}`` + - ``projects/{projectID}`` cloud_control_metadata (google.cloud.cloudsecuritycompliance_v1.types.CloudControlMetadata): - Required. Deployment mode and parameters for - the Cloud Control. + Required. The deployment mode and parameters + for the cloud control. description (str): - Optional. User provided description of the - CloudControl deployment + Optional. A friendly description for the + cloud control deployment. deployment_state (google.cloud.cloudsecuritycompliance_v1.types.DeploymentState): - Output only. State of the CloudControl - deployment + Output only. The state of the cloud control + deployment. create_time (google.protobuf.timestamp_pb2.Timestamp): - Output only. The time at which the resource - was created. + Output only. The time when the resource was + created. update_time (google.protobuf.timestamp_pb2.Timestamp): - Output only. The time at which the resource + Output only. The time when the resource was last updated. etag (str): Optional. To prevent concurrent updates from overwriting - each other, always provide the ``etag`` when you update a - CloudControlDeployment. You can also provide the ``etag`` - when you delete a CloudControlDeployment, to help ensure - that you're deleting the intended version of the - CloudControlDeployment. + each other, provide the ``etag`` when you update a cloud + control deployment. You can also provide the ``etag`` when + you delete a cloud control deployment to help ensure that + you're deleting the intended version of the deployment. parameter_substituted_cloud_control (google.cloud.cloudsecuritycompliance_v1.types.CloudControl): - Output only. The CloudControl after - substitution of given parameters. + Output only. The cloud control after the + given parameters are substituted. framework_deployment_references (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeploymentReference]): - Output only. The references to the Framework - deployments that this Cloud Control deployment - is part of. A Cloud Control deployment can be - part of multiple Framework deployments. + Output only. The references to the framework + deployments that this cloud control deployment + is part of. A cloud control deployment can be + part of multiple framework deployments. target_resource_display_name (str): Output only. The display name of the target resource. @@ -336,8 +342,8 @@ class CloudControlDeployment(proto.Message): class TargetResourceConfig(proto.Message): - r"""TargetResourceConfig contains either the name of the target_resource - or contains the config to create a new target_resource. + r"""The name of the target resource or the configuration that's + required to create a new target resource. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -348,14 +354,18 @@ class TargetResourceConfig(proto.Message): Attributes: existing_target_resource (str): - Optional. CRM node in format - organizations/{organization}, folders/{folder}, - or projects/{project} + Optional. The resource hierarchy node, in one of the + following formats: + + - ``organizations/{organizationID}`` + - ``folders/{folderID}`` + - ``projects/{projectID}`` This field is a member of `oneof`_ ``resource_config``. target_resource_creation_config (google.cloud.cloudsecuritycompliance_v1.types.TargetResourceCreationConfig): - Optional. Config to create a new resource and use that as - the target_resource for deployment. + Optional. The details that are required to + create a resource and use that resource as the + target resource for deployment. This field is a member of `oneof`_ ``resource_config``. """ @@ -374,8 +384,8 @@ class TargetResourceConfig(proto.Message): class TargetResourceCreationConfig(proto.Message): - r"""TargetResourceCreationConfig contains the config to create a new - resource to be used as the target_resource of a deployment. + r"""The configuration that's required to create a target + resource. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -386,13 +396,13 @@ class TargetResourceCreationConfig(proto.Message): Attributes: folder_creation_config (google.cloud.cloudsecuritycompliance_v1.types.FolderCreationConfig): - Optional. Config to create a new folder to be used as the - target_resource of a deployment. + Optional. The configuration that's required + to create a folder. This field is a member of `oneof`_ ``resource_creation_config``. project_creation_config (google.cloud.cloudsecuritycompliance_v1.types.ProjectCreationConfig): - Optional. Config to create a new project to be used as the - target_resource of a deployment. + Optional. The configuration that's required + to create a project. This field is a member of `oneof`_ ``resource_creation_config``. """ @@ -412,17 +422,16 @@ class TargetResourceCreationConfig(proto.Message): class FolderCreationConfig(proto.Message): - r"""FolderCreationConfig contains the config to create a new folder to - be used as the target_resource of a deployment. + r"""The configuration that's required to create a folder to be + used as the target resource for a deployment. Attributes: parent (str): - Required. The parent of the folder to be - created. It can be an organizations/{org} or - folders/{folder} + Required. The parent of the folder, in the format + ``organizations/{organizationID}`` or + ``folders/{folderID}``. folder_display_name (str): - Required. Display name of the folder to be - created + Required. The display name of the folder. """ parent: str = proto.Field( @@ -436,19 +445,19 @@ class FolderCreationConfig(proto.Message): class ProjectCreationConfig(proto.Message): - r"""ProjectCreationConfig contains the config to create a new project to - be used as the target_resource of a deployment. + r"""The configuration that's required to create a project to be + used as the target resource of a deployment. Attributes: parent (str): - Required. organizations/{org} or - folders/{folder} + Required. The parent of the project, in the format + ``organizations/{organizationID}`` or + ``folders/{folderID}``. project_display_name (str): - Required. Display name of the project to be - created. + Required. The display name of the project. billing_account_id (str): - Required. Billing account id to be used for - the project. + Required. The billing account ID for the + project. """ parent: str = proto.Field( @@ -466,15 +475,16 @@ class ProjectCreationConfig(proto.Message): class CloudControlMetadata(proto.Message): - r"""CloudControlMetadata contains the enforcement mode and - parameters of a Cloud Control Deployment. + r"""The enforcement mode and parameters of a cloud + control deployment. Attributes: cloud_control_details (google.cloud.cloudsecuritycompliance_v1.types.CloudControlDetails): - Required. Cloud control name and parameters. + Required. The cloud control name and + parameters. enforcement_mode (google.cloud.cloudsecuritycompliance_v1.types.EnforcementMode): - Required. Enforcement mode of the cloud - control + Required. The enforcement mode of the cloud + control. """ cloud_control_details: common.CloudControlDetails = proto.Field( @@ -490,22 +500,22 @@ class CloudControlMetadata(proto.Message): class CreateFrameworkDeploymentRequest(proto.Message): - r"""Request message for CreateFrameworkDeployment API. + r"""The request message for [CreateFrameworkDeployment][]. Attributes: parent (str): - Required. The parent resource of the - FrameworkDeployment in the format: - organizations/{organization}/locations/{location} - Only global location is supported. + Required. The parent resource of the framework deployment in + the format + ``organizations/{organization}/locations/{location}``. Only + the global location is supported. framework_deployment_id (str): - Optional. User provided identifier. It should - be unique in scope of a parent. This is optional - and if not provided, a random UUID will be - generated. + Optional. An identifier for the framework + deployment that's unique in scope of the parent. + If you don't specify a value, then a random UUID + is generated. framework_deployment (google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeployment): - Required. The FrameworkDeployment to be - created. + Required. The framework deployment that + you're creating. """ parent: str = proto.Field( @@ -524,20 +534,21 @@ class CreateFrameworkDeploymentRequest(proto.Message): class DeleteFrameworkDeploymentRequest(proto.Message): - r"""Request message for DeleteFrameworkDeployment. + r"""The request message for [DeleteFrameworkDeployment][]. Attributes: name (str): - Required. name of the FrameworkDeployment to be deleted in - the following format: - organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id} + Required. The name of the framework deployment that you want + to delete, in the format + ``organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id}``. + The only supported location is ``global``. etag (str): Optional. An opaque identifier for the current version of the resource. If you provide this value, then it must match the existing value. If the values don't match, then the request fails - with an [ABORTED][google.rpc.Code.ABORTED] error. + with an [``ABORTED``][google.rpc.Code.ABORTED] error. If you omit this value, then the resource is deleted regardless of its current ``etag`` value. @@ -554,12 +565,14 @@ class DeleteFrameworkDeploymentRequest(proto.Message): class GetFrameworkDeploymentRequest(proto.Message): - r"""Request message for GetFrameworkDeployment. + r"""The request message for [GetFrameworkDeployment][]. Attributes: name (str): - Required. FrameworkDeployment name in the following format: - organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id} + Required. The name of the framework deployment, in the + format + ``organizations/{organization}/locations/{location}/frameworkDeployments/{framework_deployment_id}``. + The only supported location is ``global``. """ name: str = proto.Field( @@ -569,29 +582,35 @@ class GetFrameworkDeploymentRequest(proto.Message): class ListFrameworkDeploymentsRequest(proto.Message): - r"""Request message for ListFrameworkDeployments. + r"""The request message for [ListFrameworkDeployments][]. Attributes: parent (str): - Required. parent resource of the - FrameworkDeployment in the format: - organizations/{organization}/locations/{location} - Only global location is supported. + Required. The parent resource of the framework deployment, + in the format + ``organizations/{organization}/locations/{location}``. The + only supported location is ``global``. page_size (int): - Optional. Requested page size. Server may - return fewer items than requested. If - unspecified, server will pick an appropriate + Optional. The requested page size. The server + might return fewer items than requested. + If unspecified, the server picks an appropriate default. page_token (str): - Optional. A token identifying a page of + Optional. A token that identifies a page of results the server should return. filter (str): - Optional. Filter to be applied on the - resource, defined by EBNF grammar - https://google.aip.dev/assets/misc/ebnf-filtering.txt. + Optional. The filter to be applied on the resource, as + defined by `AIP-160: + Filtering `__. order_by (str): - Optional. Sort results. Supported are "name", - "name desc" or "" (unsorted). + Optional. The sort order for the results. The following + values are supported: + + - ``name`` + - ``name desc`` + + If you do not specify a value, then the results are not + sorted. """ parent: str = proto.Field( @@ -617,14 +636,14 @@ class ListFrameworkDeploymentsRequest(proto.Message): class ListFrameworkDeploymentsResponse(proto.Message): - r"""Response message for ListFrameworkDeployments. + r"""The response message for [ListFrameworkDeployments][]. Attributes: framework_deployments (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.FrameworkDeployment]): - The list of FrameworkDeployments. + The list of framework deployments. next_page_token (str): - A token identifying a page of results the - server should return. + A token that identifies the next page of + results that the server should return. """ @property @@ -643,13 +662,14 @@ def raw_page(self): class GetCloudControlDeploymentRequest(proto.Message): - r"""Request message for GetCloudControlDeployment. + r"""The request message for [GetCloudControlDeployment][]. Attributes: name (str): - Required. CloudControlDeployment name in the following - format: - organizations/{organization}/locations/{location}/cloudControlDeployments/{cloud_control_deployment_id} + Required. The name for the cloud control deployment, in the + format + ``organizations/{organization}/locations/{location}/cloudControlDeployments/{cloud_control_deployment_id}``. + The only supported location is ``global``. """ name: str = proto.Field( @@ -659,29 +679,34 @@ class GetCloudControlDeploymentRequest(proto.Message): class ListCloudControlDeploymentsRequest(proto.Message): - r"""Request message for ListCloudControlDeployments. + r"""The request message for [ListCloudControlDeployments][]. Attributes: parent (str): - Required. parent resource of the - CloudControlDeployment in the format: - organizations/{organization}/locations/{location} - Only global location is supported. + Required. The parent resource for the cloud control + deployment, in the format + ``organizations/{organization}/locations/{location}``. The + only supported location is ``global``. page_size (int): - Optional. Requested page size. Server may - return fewer items than requested. If - unspecified, server will pick an appropriate + Optional. The requested page size. The server + might return fewer items than you requested. + If unspecified, the server picks an appropriate default. page_token (str): - Optional. A token identifying a page of - results the server should return. + Optional. A token that identifies the page of + results that the server should return. filter (str): - Optional. Filter to be applied on the - resource, defined by EBNF grammar - https://google.aip.dev/assets/misc/ebnf-filtering.txt. + Optional. The filter to apply on the resource, as defined by + `AIP-160: Filtering `__. order_by (str): - Optional. Sort results. Supported are "name", - "name desc" or "" (unsorted). + Optional. The sort order for the results. The following + values are supported: + + - ``name`` + - ``name desc`` + + If you do not specify a value, then the results are not + sorted. """ parent: str = proto.Field( @@ -707,14 +732,14 @@ class ListCloudControlDeploymentsRequest(proto.Message): class ListCloudControlDeploymentsResponse(proto.Message): - r"""Response message for ListCloudControlDeployments. + r"""The response message for [ListCloudControlDeployments][]. Attributes: cloud_control_deployments (MutableSequence[google.cloud.cloudsecuritycompliance_v1.types.CloudControlDeployment]): - The list of CloudControlDeployments. + The list of cloud control deployments. next_page_token (str): - A token identifying a page of results the - server should return. + A token that identifies the next page of + results that the server should return. """ @property @@ -735,13 +760,14 @@ def raw_page(self): class CloudControlDeploymentReference(proto.Message): - r"""The reference to a CloudControlDeployment. + r"""The reference to a cloud control deployment. Attributes: cloud_control_deployment (str): Output only. The name of the CloudControlDeployment. The - format is: - organizations/{org}/locations/{location}/cloudControlDeployments/{cloud_control_deployment_id} + format is + ``organizations/{org}/locations/{location}/cloudControlDeployments/{cloud_control_deployment_id}``. + The only supported location is ``global``. """ cloud_control_deployment: str = proto.Field( @@ -751,21 +777,30 @@ class CloudControlDeploymentReference(proto.Message): class FrameworkDeploymentReference(proto.Message): - r"""The reference to a FrameworkDeployment. + r"""The reference to a framework deployment. Attributes: framework_deployment (str): - Output only. The name of the FrameworkDeployment. The format - is: - organizations/{org}/locations/{location}/frameworkDeployments/{framework_deployment_id} + Output only. The name of the framework deployment, in the + format + ``organizations/{org}/locations/{location}/frameworkDeployments/{framework_deployment_id}``. + The only supported location is ``global``. framework_reference (google.cloud.cloudsecuritycompliance_v1.types.FrameworkReference): - Optional. The reference to the Framework that this - deployment is for. Example: { framework: - "organizations/{org}/locations/{location}/frameworks/{framework}", - major_revision_id: 1 } + Optional. The reference to the framework that this + deployment is for. For example: + + :: + + { + framework: + "organizations/{org}/locations/{location}/frameworks/{framework}", + major_revision_id: 1 + } + + The only supported location is ``global``. framework_display_name (str): - Optional. The display name of the Framework - that this FrameworkDeployment is for. + Optional. The display name of the framework + that this framework deployment is for. """ framework_deployment: str = proto.Field( diff --git a/packages/google-cloud-cloudsecuritycompliance/noxfile.py b/packages/google-cloud-cloudsecuritycompliance/noxfile.py index af43896844ef..e4eb3ebb0ced 100644 --- a/packages/google-cloud-cloudsecuritycompliance/noxfile.py +++ b/packages/google-cloud-cloudsecuritycompliance/noxfile.py @@ -27,6 +27,10 @@ LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] +# Add samples to the list of directories to format if the directory exists. +if os.path.isdir("samples"): + LINT_PATHS.append("samples") + ALL_PYTHON = [ "3.7", "3.8", diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_create_framework_audit_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_create_framework_audit_async.py new file mode 100644 index 000000000000..1389c6126c31 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_create_framework_audit_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateFrameworkAudit +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_Audit_CreateFrameworkAudit_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +async def sample_create_framework_audit(): + # Create a client + client = cloudsecuritycompliance_v1.AuditAsyncClient() + + # Initialize request argument(s) + framework_audit = cloudsecuritycompliance_v1.FrameworkAudit() + framework_audit.framework_audit_destination.bucket.bucket_uri = "bucket_uri_value" + + request = cloudsecuritycompliance_v1.CreateFrameworkAuditRequest( + parent="parent_value", + framework_audit=framework_audit, + ) + + # Make the request + operation = client.create_framework_audit(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + +# [END cloudsecuritycompliance_v1_generated_Audit_CreateFrameworkAudit_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_create_framework_audit_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_create_framework_audit_sync.py new file mode 100644 index 000000000000..8a74648049cc --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_create_framework_audit_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateFrameworkAudit +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_Audit_CreateFrameworkAudit_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +def sample_create_framework_audit(): + # Create a client + client = cloudsecuritycompliance_v1.AuditClient() + + # Initialize request argument(s) + framework_audit = cloudsecuritycompliance_v1.FrameworkAudit() + framework_audit.framework_audit_destination.bucket.bucket_uri = "bucket_uri_value" + + request = cloudsecuritycompliance_v1.CreateFrameworkAuditRequest( + parent="parent_value", + framework_audit=framework_audit, + ) + + # Make the request + operation = client.create_framework_audit(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END cloudsecuritycompliance_v1_generated_Audit_CreateFrameworkAudit_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_generate_framework_audit_scope_report_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_generate_framework_audit_scope_report_async.py new file mode 100644 index 000000000000..3510fc8f235c --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_generate_framework_audit_scope_report_async.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GenerateFrameworkAuditScopeReport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_Audit_GenerateFrameworkAuditScopeReport_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +async def sample_generate_framework_audit_scope_report(): + # Create a client + client = cloudsecuritycompliance_v1.AuditAsyncClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.GenerateFrameworkAuditScopeReportRequest( + scope="scope_value", + report_format="ODF", + compliance_framework="compliance_framework_value", + ) + + # Make the request + response = await client.generate_framework_audit_scope_report(request=request) + + # Handle the response + print(response) + + +# [END cloudsecuritycompliance_v1_generated_Audit_GenerateFrameworkAuditScopeReport_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_generate_framework_audit_scope_report_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_generate_framework_audit_scope_report_sync.py new file mode 100644 index 000000000000..892e8ef8a051 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_generate_framework_audit_scope_report_sync.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GenerateFrameworkAuditScopeReport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_Audit_GenerateFrameworkAuditScopeReport_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +def sample_generate_framework_audit_scope_report(): + # Create a client + client = cloudsecuritycompliance_v1.AuditClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.GenerateFrameworkAuditScopeReportRequest( + scope="scope_value", + report_format="ODF", + compliance_framework="compliance_framework_value", + ) + + # Make the request + response = client.generate_framework_audit_scope_report(request=request) + + # Handle the response + print(response) + + +# [END cloudsecuritycompliance_v1_generated_Audit_GenerateFrameworkAuditScopeReport_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_get_framework_audit_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_get_framework_audit_async.py new file mode 100644 index 000000000000..8e1da43b0f31 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_get_framework_audit_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetFrameworkAudit +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_Audit_GetFrameworkAudit_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +async def sample_get_framework_audit(): + # Create a client + client = cloudsecuritycompliance_v1.AuditAsyncClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.GetFrameworkAuditRequest( + name="name_value", + ) + + # Make the request + response = await client.get_framework_audit(request=request) + + # Handle the response + print(response) + + +# [END cloudsecuritycompliance_v1_generated_Audit_GetFrameworkAudit_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_get_framework_audit_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_get_framework_audit_sync.py new file mode 100644 index 000000000000..76d4858f2dfd --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_get_framework_audit_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetFrameworkAudit +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_Audit_GetFrameworkAudit_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +def sample_get_framework_audit(): + # Create a client + client = cloudsecuritycompliance_v1.AuditClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.GetFrameworkAuditRequest( + name="name_value", + ) + + # Make the request + response = client.get_framework_audit(request=request) + + # Handle the response + print(response) + + +# [END cloudsecuritycompliance_v1_generated_Audit_GetFrameworkAudit_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_list_framework_audits_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_list_framework_audits_async.py new file mode 100644 index 000000000000..5cef4a7a528b --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_list_framework_audits_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListFrameworkAudits +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_Audit_ListFrameworkAudits_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +async def sample_list_framework_audits(): + # Create a client + client = cloudsecuritycompliance_v1.AuditAsyncClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.ListFrameworkAuditsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_framework_audits(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END cloudsecuritycompliance_v1_generated_Audit_ListFrameworkAudits_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_list_framework_audits_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_list_framework_audits_sync.py new file mode 100644 index 000000000000..4ad215d2818f --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_audit_list_framework_audits_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListFrameworkAudits +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_Audit_ListFrameworkAudits_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +def sample_list_framework_audits(): + # Create a client + client = cloudsecuritycompliance_v1.AuditClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.ListFrameworkAuditsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_framework_audits(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END cloudsecuritycompliance_v1_generated_Audit_ListFrameworkAudits_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_calculate_effective_cm_enrollment_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_calculate_effective_cm_enrollment_async.py new file mode 100644 index 000000000000..dd05c54ddc9e --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_calculate_effective_cm_enrollment_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CalculateEffectiveCmEnrollment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_CmEnrollmentService_CalculateEffectiveCmEnrollment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +async def sample_calculate_effective_cm_enrollment(): + # Create a client + client = cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.CalculateEffectiveCmEnrollmentRequest( + name="name_value", + ) + + # Make the request + response = await client.calculate_effective_cm_enrollment(request=request) + + # Handle the response + print(response) + + +# [END cloudsecuritycompliance_v1_generated_CmEnrollmentService_CalculateEffectiveCmEnrollment_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_calculate_effective_cm_enrollment_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_calculate_effective_cm_enrollment_sync.py new file mode 100644 index 000000000000..9baa5e012991 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_calculate_effective_cm_enrollment_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CalculateEffectiveCmEnrollment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_CmEnrollmentService_CalculateEffectiveCmEnrollment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +def sample_calculate_effective_cm_enrollment(): + # Create a client + client = cloudsecuritycompliance_v1.CmEnrollmentServiceClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.CalculateEffectiveCmEnrollmentRequest( + name="name_value", + ) + + # Make the request + response = client.calculate_effective_cm_enrollment(request=request) + + # Handle the response + print(response) + + +# [END cloudsecuritycompliance_v1_generated_CmEnrollmentService_CalculateEffectiveCmEnrollment_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_update_cm_enrollment_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_update_cm_enrollment_async.py new file mode 100644 index 000000000000..72205cd465d8 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_update_cm_enrollment_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateCmEnrollment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_CmEnrollmentService_UpdateCmEnrollment_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +async def sample_update_cm_enrollment(): + # Create a client + client = cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.UpdateCmEnrollmentRequest() + + # Make the request + response = await client.update_cm_enrollment(request=request) + + # Handle the response + print(response) + + +# [END cloudsecuritycompliance_v1_generated_CmEnrollmentService_UpdateCmEnrollment_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_update_cm_enrollment_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_update_cm_enrollment_sync.py new file mode 100644 index 000000000000..f3314230c532 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_cm_enrollment_service_update_cm_enrollment_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateCmEnrollment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-cloudsecuritycompliance + + +# [START cloudsecuritycompliance_v1_generated_CmEnrollmentService_UpdateCmEnrollment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import cloudsecuritycompliance_v1 + + +def sample_update_cm_enrollment(): + # Create a client + client = cloudsecuritycompliance_v1.CmEnrollmentServiceClient() + + # Initialize request argument(s) + request = cloudsecuritycompliance_v1.UpdateCmEnrollmentRequest() + + # Make the request + response = client.update_cm_enrollment(request=request) + + # Handle the response + print(response) + + +# [END cloudsecuritycompliance_v1_generated_CmEnrollmentService_UpdateCmEnrollment_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_cloud_control_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_cloud_control_async.py index 429921dcfc3b..1941ff52188a 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_cloud_control_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_cloud_control_async.py @@ -54,4 +54,5 @@ async def sample_create_cloud_control(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_CreateCloudControl_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_cloud_control_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_cloud_control_sync.py index 8a369e7a9253..bde0f2bc1b62 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_cloud_control_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_cloud_control_sync.py @@ -54,4 +54,5 @@ def sample_create_cloud_control(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_CreateCloudControl_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_framework_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_framework_async.py index a4345641a832..11adfc5da65f 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_framework_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_framework_async.py @@ -54,4 +54,5 @@ async def sample_create_framework(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_CreateFramework_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_framework_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_framework_sync.py index a2145d53353f..afcee671f989 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_framework_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_create_framework_sync.py @@ -54,4 +54,5 @@ def sample_create_framework(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_CreateFramework_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_cloud_control_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_cloud_control_async.py index 3b314dd5876a..d2e9c44c4971 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_cloud_control_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_cloud_control_async.py @@ -49,4 +49,5 @@ async def sample_get_cloud_control(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_GetCloudControl_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_cloud_control_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_cloud_control_sync.py index c6a5c43a41d1..5c1da9cb81ff 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_cloud_control_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_cloud_control_sync.py @@ -49,4 +49,5 @@ def sample_get_cloud_control(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_GetCloudControl_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_framework_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_framework_async.py index 8161c6bb8d73..2581f4aee97d 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_framework_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_framework_async.py @@ -49,4 +49,5 @@ async def sample_get_framework(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_GetFramework_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_framework_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_framework_sync.py index 7070206078a2..1a18284721f2 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_framework_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_get_framework_sync.py @@ -49,4 +49,5 @@ def sample_get_framework(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_GetFramework_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_cloud_controls_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_cloud_controls_async.py index d4dbcbb3e680..b5615921b884 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_cloud_controls_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_cloud_controls_async.py @@ -50,4 +50,5 @@ async def sample_list_cloud_controls(): async for response in page_result: print(response) + # [END cloudsecuritycompliance_v1_generated_Config_ListCloudControls_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_cloud_controls_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_cloud_controls_sync.py index fe8a922dff5f..f02ea6bbecde 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_cloud_controls_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_cloud_controls_sync.py @@ -50,4 +50,5 @@ def sample_list_cloud_controls(): for response in page_result: print(response) + # [END cloudsecuritycompliance_v1_generated_Config_ListCloudControls_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_frameworks_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_frameworks_async.py index dd1251c4b019..82d14decea71 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_frameworks_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_frameworks_async.py @@ -50,4 +50,5 @@ async def sample_list_frameworks(): async for response in page_result: print(response) + # [END cloudsecuritycompliance_v1_generated_Config_ListFrameworks_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_frameworks_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_frameworks_sync.py index 6b24c856e639..c01fa7f68dfd 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_frameworks_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_list_frameworks_sync.py @@ -50,4 +50,5 @@ def sample_list_frameworks(): for response in page_result: print(response) + # [END cloudsecuritycompliance_v1_generated_Config_ListFrameworks_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_cloud_control_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_cloud_control_async.py index adbe7403745a..889d35de7b4f 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_cloud_control_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_cloud_control_async.py @@ -52,4 +52,5 @@ async def sample_update_cloud_control(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_UpdateCloudControl_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_cloud_control_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_cloud_control_sync.py index 89614bf1407d..6c9a8737bd4f 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_cloud_control_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_cloud_control_sync.py @@ -52,4 +52,5 @@ def sample_update_cloud_control(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_UpdateCloudControl_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_framework_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_framework_async.py index 611c51f298d8..d8c4ab20821f 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_framework_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_framework_async.py @@ -52,4 +52,5 @@ async def sample_update_framework(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_UpdateFramework_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_framework_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_framework_sync.py index e996ef709e4f..1913edb8b05b 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_framework_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_config_update_framework_sync.py @@ -52,4 +52,5 @@ def sample_update_framework(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Config_UpdateFramework_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_create_framework_deployment_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_create_framework_deployment_async.py index ad2d812ce311..e1f4a1a517fc 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_create_framework_deployment_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_create_framework_deployment_async.py @@ -40,10 +40,16 @@ async def sample_create_framework_deployment(): # Initialize request argument(s) framework_deployment = cloudsecuritycompliance_v1.FrameworkDeployment() - framework_deployment.target_resource_config.existing_target_resource = "existing_target_resource_value" + framework_deployment.target_resource_config.existing_target_resource = ( + "existing_target_resource_value" + ) framework_deployment.framework.framework = "framework_value" - framework_deployment.cloud_control_metadata.cloud_control_details.name = "name_value" - framework_deployment.cloud_control_metadata.cloud_control_details.major_revision_id = 1811 + framework_deployment.cloud_control_metadata.cloud_control_details.name = ( + "name_value" + ) + framework_deployment.cloud_control_metadata.cloud_control_details.major_revision_id = ( + 1811 + ) framework_deployment.cloud_control_metadata.enforcement_mode = "AUDIT" request = cloudsecuritycompliance_v1.CreateFrameworkDeploymentRequest( @@ -61,4 +67,5 @@ async def sample_create_framework_deployment(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_CreateFrameworkDeployment_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_create_framework_deployment_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_create_framework_deployment_sync.py index ebed85e6f0fd..473f826d185d 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_create_framework_deployment_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_create_framework_deployment_sync.py @@ -40,10 +40,16 @@ def sample_create_framework_deployment(): # Initialize request argument(s) framework_deployment = cloudsecuritycompliance_v1.FrameworkDeployment() - framework_deployment.target_resource_config.existing_target_resource = "existing_target_resource_value" + framework_deployment.target_resource_config.existing_target_resource = ( + "existing_target_resource_value" + ) framework_deployment.framework.framework = "framework_value" - framework_deployment.cloud_control_metadata.cloud_control_details.name = "name_value" - framework_deployment.cloud_control_metadata.cloud_control_details.major_revision_id = 1811 + framework_deployment.cloud_control_metadata.cloud_control_details.name = ( + "name_value" + ) + framework_deployment.cloud_control_metadata.cloud_control_details.major_revision_id = ( + 1811 + ) framework_deployment.cloud_control_metadata.enforcement_mode = "AUDIT" request = cloudsecuritycompliance_v1.CreateFrameworkDeploymentRequest( @@ -61,4 +67,5 @@ def sample_create_framework_deployment(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_CreateFrameworkDeployment_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_delete_framework_deployment_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_delete_framework_deployment_async.py index 6b256ca4369e..211b8a291bb9 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_delete_framework_deployment_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_delete_framework_deployment_async.py @@ -53,4 +53,5 @@ async def sample_delete_framework_deployment(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_DeleteFrameworkDeployment_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_delete_framework_deployment_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_delete_framework_deployment_sync.py index 60379236b2da..d81a35d79976 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_delete_framework_deployment_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_delete_framework_deployment_sync.py @@ -53,4 +53,5 @@ def sample_delete_framework_deployment(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_DeleteFrameworkDeployment_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_cloud_control_deployment_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_cloud_control_deployment_async.py index 6245bc89d57c..fcaedaa37f77 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_cloud_control_deployment_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_cloud_control_deployment_async.py @@ -49,4 +49,5 @@ async def sample_get_cloud_control_deployment(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_GetCloudControlDeployment_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_cloud_control_deployment_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_cloud_control_deployment_sync.py index b08e78995b69..0eb2dc3c3beb 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_cloud_control_deployment_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_cloud_control_deployment_sync.py @@ -49,4 +49,5 @@ def sample_get_cloud_control_deployment(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_GetCloudControlDeployment_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_framework_deployment_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_framework_deployment_async.py index 17c9b6eae4f0..ed7fb878adf1 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_framework_deployment_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_framework_deployment_async.py @@ -49,4 +49,5 @@ async def sample_get_framework_deployment(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_GetFrameworkDeployment_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_framework_deployment_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_framework_deployment_sync.py index f89fd82c3dea..cf84304c0d77 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_framework_deployment_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_get_framework_deployment_sync.py @@ -49,4 +49,5 @@ def sample_get_framework_deployment(): # Handle the response print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_GetFrameworkDeployment_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_cloud_control_deployments_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_cloud_control_deployments_async.py index 1bee318194c8..afb669532ecd 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_cloud_control_deployments_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_cloud_control_deployments_async.py @@ -50,4 +50,5 @@ async def sample_list_cloud_control_deployments(): async for response in page_result: print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_ListCloudControlDeployments_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_cloud_control_deployments_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_cloud_control_deployments_sync.py index 13653baee0d1..6501f9209c9c 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_cloud_control_deployments_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_cloud_control_deployments_sync.py @@ -50,4 +50,5 @@ def sample_list_cloud_control_deployments(): for response in page_result: print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_ListCloudControlDeployments_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_framework_deployments_async.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_framework_deployments_async.py index cb86feca4b52..e0604a33bdc4 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_framework_deployments_async.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_framework_deployments_async.py @@ -50,4 +50,5 @@ async def sample_list_framework_deployments(): async for response in page_result: print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_ListFrameworkDeployments_async] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_framework_deployments_sync.py b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_framework_deployments_sync.py index 295699aa10f5..5fefbbc7c381 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_framework_deployments_sync.py +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/cloudsecuritycompliance_v1_generated_deployment_list_framework_deployments_sync.py @@ -50,4 +50,5 @@ def sample_list_framework_deployments(): for response in page_result: print(response) + # [END cloudsecuritycompliance_v1_generated_Deployment_ListFrameworkDeployments_sync] diff --git a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/snippet_metadata_google.cloud.cloudsecuritycompliance.v1.json b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/snippet_metadata_google.cloud.cloudsecuritycompliance.v1.json index 5e20f5fcbc13..4a4fcab781bf 100644 --- a/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/snippet_metadata_google.cloud.cloudsecuritycompliance.v1.json +++ b/packages/google-cloud-cloudsecuritycompliance/samples/generated_samples/snippet_metadata_google.cloud.cloudsecuritycompliance.v1.json @@ -11,6 +11,1012 @@ "version": "0.3.0" }, "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient", + "shortName": "AuditAsyncClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient.create_framework_audit", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit.CreateFrameworkAudit", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "shortName": "Audit" + }, + "shortName": "CreateFrameworkAudit" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.CreateFrameworkAuditRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "framework_audit", + "type": "google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit" + }, + { + "name": "framework_audit_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "create_framework_audit" + }, + "description": "Sample for CreateFrameworkAudit", + "file": "cloudsecuritycompliance_v1_generated_audit_create_framework_audit_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_Audit_CreateFrameworkAudit_async", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_audit_create_framework_audit_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditClient", + "shortName": "AuditClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditClient.create_framework_audit", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit.CreateFrameworkAudit", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "shortName": "Audit" + }, + "shortName": "CreateFrameworkAudit" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.CreateFrameworkAuditRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "framework_audit", + "type": "google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit" + }, + { + "name": "framework_audit_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "create_framework_audit" + }, + "description": "Sample for CreateFrameworkAudit", + "file": "cloudsecuritycompliance_v1_generated_audit_create_framework_audit_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_Audit_CreateFrameworkAudit_sync", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_audit_create_framework_audit_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient", + "shortName": "AuditAsyncClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient.generate_framework_audit_scope_report", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit.GenerateFrameworkAuditScopeReport", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "shortName": "Audit" + }, + "shortName": "GenerateFrameworkAuditScopeReport" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportRequest" + }, + { + "name": "scope", + "type": "str" + }, + { + "name": "report_format", + "type": "google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportRequest.Format" + }, + { + "name": "compliance_framework", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportResponse", + "shortName": "generate_framework_audit_scope_report" + }, + "description": "Sample for GenerateFrameworkAuditScopeReport", + "file": "cloudsecuritycompliance_v1_generated_audit_generate_framework_audit_scope_report_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_Audit_GenerateFrameworkAuditScopeReport_async", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_audit_generate_framework_audit_scope_report_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditClient", + "shortName": "AuditClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditClient.generate_framework_audit_scope_report", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit.GenerateFrameworkAuditScopeReport", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "shortName": "Audit" + }, + "shortName": "GenerateFrameworkAuditScopeReport" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportRequest" + }, + { + "name": "scope", + "type": "str" + }, + { + "name": "report_format", + "type": "google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportRequest.Format" + }, + { + "name": "compliance_framework", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.cloudsecuritycompliance_v1.types.GenerateFrameworkAuditScopeReportResponse", + "shortName": "generate_framework_audit_scope_report" + }, + "description": "Sample for GenerateFrameworkAuditScopeReport", + "file": "cloudsecuritycompliance_v1_generated_audit_generate_framework_audit_scope_report_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_Audit_GenerateFrameworkAuditScopeReport_sync", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_audit_generate_framework_audit_scope_report_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient", + "shortName": "AuditAsyncClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient.get_framework_audit", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit.GetFrameworkAudit", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "shortName": "Audit" + }, + "shortName": "GetFrameworkAudit" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.GetFrameworkAuditRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit", + "shortName": "get_framework_audit" + }, + "description": "Sample for GetFrameworkAudit", + "file": "cloudsecuritycompliance_v1_generated_audit_get_framework_audit_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_Audit_GetFrameworkAudit_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_audit_get_framework_audit_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditClient", + "shortName": "AuditClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditClient.get_framework_audit", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit.GetFrameworkAudit", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "shortName": "Audit" + }, + "shortName": "GetFrameworkAudit" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.GetFrameworkAuditRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.cloudsecuritycompliance_v1.types.FrameworkAudit", + "shortName": "get_framework_audit" + }, + "description": "Sample for GetFrameworkAudit", + "file": "cloudsecuritycompliance_v1_generated_audit_get_framework_audit_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_Audit_GetFrameworkAudit_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_audit_get_framework_audit_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient", + "shortName": "AuditAsyncClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditAsyncClient.list_framework_audits", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit.ListFrameworkAudits", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "shortName": "Audit" + }, + "shortName": "ListFrameworkAudits" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.cloudsecuritycompliance_v1.services.audit.pagers.ListFrameworkAuditsAsyncPager", + "shortName": "list_framework_audits" + }, + "description": "Sample for ListFrameworkAudits", + "file": "cloudsecuritycompliance_v1_generated_audit_list_framework_audits_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_Audit_ListFrameworkAudits_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_audit_list_framework_audits_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditClient", + "shortName": "AuditClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.AuditClient.list_framework_audits", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit.ListFrameworkAudits", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.Audit", + "shortName": "Audit" + }, + "shortName": "ListFrameworkAudits" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.ListFrameworkAuditsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.cloudsecuritycompliance_v1.services.audit.pagers.ListFrameworkAuditsPager", + "shortName": "list_framework_audits" + }, + "description": "Sample for ListFrameworkAudits", + "file": "cloudsecuritycompliance_v1_generated_audit_list_framework_audits_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_Audit_ListFrameworkAudits_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_audit_list_framework_audits_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient", + "shortName": "CmEnrollmentServiceAsyncClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient.calculate_effective_cm_enrollment", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService.CalculateEffectiveCmEnrollment", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "shortName": "CmEnrollmentService" + }, + "shortName": "CalculateEffectiveCmEnrollment" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.CalculateEffectiveCmEnrollmentRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.cloudsecuritycompliance_v1.types.CalculateEffectiveCmEnrollmentResponse", + "shortName": "calculate_effective_cm_enrollment" + }, + "description": "Sample for CalculateEffectiveCmEnrollment", + "file": "cloudsecuritycompliance_v1_generated_cm_enrollment_service_calculate_effective_cm_enrollment_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_CmEnrollmentService_CalculateEffectiveCmEnrollment_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_cm_enrollment_service_calculate_effective_cm_enrollment_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient", + "shortName": "CmEnrollmentServiceClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.calculate_effective_cm_enrollment", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService.CalculateEffectiveCmEnrollment", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "shortName": "CmEnrollmentService" + }, + "shortName": "CalculateEffectiveCmEnrollment" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.CalculateEffectiveCmEnrollmentRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.cloudsecuritycompliance_v1.types.CalculateEffectiveCmEnrollmentResponse", + "shortName": "calculate_effective_cm_enrollment" + }, + "description": "Sample for CalculateEffectiveCmEnrollment", + "file": "cloudsecuritycompliance_v1_generated_cm_enrollment_service_calculate_effective_cm_enrollment_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_CmEnrollmentService_CalculateEffectiveCmEnrollment_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_cm_enrollment_service_calculate_effective_cm_enrollment_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient", + "shortName": "CmEnrollmentServiceAsyncClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceAsyncClient.update_cm_enrollment", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService.UpdateCmEnrollment", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "shortName": "CmEnrollmentService" + }, + "shortName": "UpdateCmEnrollment" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.UpdateCmEnrollmentRequest" + }, + { + "name": "cm_enrollment", + "type": "google.cloud.cloudsecuritycompliance_v1.types.CmEnrollment" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.cloudsecuritycompliance_v1.types.CmEnrollment", + "shortName": "update_cm_enrollment" + }, + "description": "Sample for UpdateCmEnrollment", + "file": "cloudsecuritycompliance_v1_generated_cm_enrollment_service_update_cm_enrollment_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_CmEnrollmentService_UpdateCmEnrollment_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_cm_enrollment_service_update_cm_enrollment_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient", + "shortName": "CmEnrollmentServiceClient" + }, + "fullName": "google.cloud.cloudsecuritycompliance_v1.CmEnrollmentServiceClient.update_cm_enrollment", + "method": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService.UpdateCmEnrollment", + "service": { + "fullName": "google.cloud.cloudsecuritycompliance.v1.CmEnrollmentService", + "shortName": "CmEnrollmentService" + }, + "shortName": "UpdateCmEnrollment" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.cloudsecuritycompliance_v1.types.UpdateCmEnrollmentRequest" + }, + { + "name": "cm_enrollment", + "type": "google.cloud.cloudsecuritycompliance_v1.types.CmEnrollment" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.cloudsecuritycompliance_v1.types.CmEnrollment", + "shortName": "update_cm_enrollment" + }, + "description": "Sample for UpdateCmEnrollment", + "file": "cloudsecuritycompliance_v1_generated_cm_enrollment_service_update_cm_enrollment_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "cloudsecuritycompliance_v1_generated_CmEnrollmentService_UpdateCmEnrollment_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "cloudsecuritycompliance_v1_generated_cm_enrollment_service_update_cm_enrollment_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-cloudsecuritycompliance/scripts/fixup_cloudsecuritycompliance_v1_keywords.py b/packages/google-cloud-cloudsecuritycompliance/scripts/fixup_cloudsecuritycompliance_v1_keywords.py index 374bc85736fb..92224c429cf7 100644 --- a/packages/google-cloud-cloudsecuritycompliance/scripts/fixup_cloudsecuritycompliance_v1_keywords.py +++ b/packages/google-cloud-cloudsecuritycompliance/scripts/fixup_cloudsecuritycompliance_v1_keywords.py @@ -39,21 +39,27 @@ def partition( class cloudsecuritycomplianceCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'calculate_effective_cm_enrollment': ('name', ), 'create_cloud_control': ('parent', 'cloud_control_id', 'cloud_control', ), 'create_framework': ('parent', 'framework_id', 'framework', ), + 'create_framework_audit': ('parent', 'framework_audit', 'framework_audit_id', ), 'create_framework_deployment': ('parent', 'framework_deployment', 'framework_deployment_id', ), 'delete_cloud_control': ('name', ), 'delete_framework': ('name', ), 'delete_framework_deployment': ('name', 'etag', ), - 'get_cloud_control': ('name', ), + 'generate_framework_audit_scope_report': ('scope', 'report_format', 'compliance_framework', ), + 'get_cloud_control': ('name', 'major_revision_id', ), 'get_cloud_control_deployment': ('name', ), 'get_framework': ('name', 'major_revision_id', ), + 'get_framework_audit': ('name', ), 'get_framework_deployment': ('name', ), 'list_cloud_control_deployments': ('parent', 'page_size', 'page_token', 'filter', 'order_by', ), 'list_cloud_controls': ('parent', 'page_size', 'page_token', ), + 'list_framework_audits': ('parent', 'page_size', 'page_token', 'filter', ), 'list_framework_deployments': ('parent', 'page_size', 'page_token', 'filter', 'order_by', ), 'list_frameworks': ('parent', 'page_size', 'page_token', ), 'update_cloud_control': ('cloud_control', 'update_mask', ), + 'update_cm_enrollment': ('cm_enrollment', 'update_mask', ), 'update_framework': ('framework', 'update_mask', 'major_revision_id', ), } diff --git a/packages/google-cloud-cloudsecuritycompliance/tests/unit/gapic/cloudsecuritycompliance_v1/test_audit.py b/packages/google-cloud-cloudsecuritycompliance/tests/unit/gapic/cloudsecuritycompliance_v1/test_audit.py new file mode 100644 index 000000000000..e597de6c1879 --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/tests/unit/gapic/cloudsecuritycompliance_v1/test_audit.py @@ -0,0 +1,6620 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import ( + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import operation_async # type: ignore +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.services.audit import ( + AuditAsyncClient, + AuditClient, + pagers, + transports, +) +from google.cloud.cloudsecuritycompliance_v1.types import audit, common + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert AuditClient._get_default_mtls_endpoint(None) is None + assert AuditClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ( + AuditClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + ) + assert ( + AuditClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + AuditClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert AuditClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +def test__read_environment_variables(): + assert AuditClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert AuditClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert AuditClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + AuditClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert AuditClient._read_environment_variables() == (False, "never", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert AuditClient._read_environment_variables() == (False, "always", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert AuditClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + AuditClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert AuditClient._read_environment_variables() == (False, "auto", "foo.com") + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert AuditClient._get_client_cert_source(None, False) is None + assert AuditClient._get_client_cert_source(mock_provided_cert_source, False) is None + assert ( + AuditClient._get_client_cert_source(mock_provided_cert_source, True) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + AuditClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + AuditClient._get_client_cert_source(mock_provided_cert_source, "true") + is mock_provided_cert_source + ) + + +@mock.patch.object( + AuditClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuditClient), +) +@mock.patch.object( + AuditAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuditAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = AuditClient._DEFAULT_UNIVERSE + default_endpoint = AuditClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = AuditClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + AuditClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + AuditClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == AuditClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AuditClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + AuditClient._get_api_endpoint(None, None, default_universe, "always") + == AuditClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AuditClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == AuditClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AuditClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + AuditClient._get_api_endpoint(None, None, default_universe, "never") + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + AuditClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + AuditClient._get_universe_domain(client_universe_domain, universe_domain_env) + == client_universe_domain + ) + assert ( + AuditClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert AuditClient._get_universe_domain(None, None) == AuditClient._DEFAULT_UNIVERSE + + with pytest.raises(ValueError) as excinfo: + AuditClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AuditClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AuditClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (AuditClient, "grpc"), + (AuditAsyncClient, "grpc_asyncio"), + (AuditClient, "rest"), + ], +) +def test_audit_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "cloudsecuritycompliance.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://cloudsecuritycompliance.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.AuditGrpcTransport, "grpc"), + (transports.AuditGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.AuditRestTransport, "rest"), + ], +) +def test_audit_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (AuditClient, "grpc"), + (AuditAsyncClient, "grpc_asyncio"), + (AuditClient, "rest"), + ], +) +def test_audit_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "cloudsecuritycompliance.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://cloudsecuritycompliance.googleapis.com" + ) + + +def test_audit_client_get_transport_class(): + transport = AuditClient.get_transport_class() + available_transports = [ + transports.AuditGrpcTransport, + transports.AuditRestTransport, + ] + assert transport in available_transports + + transport = AuditClient.get_transport_class("grpc") + assert transport == transports.AuditGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (AuditClient, transports.AuditGrpcTransport, "grpc"), + (AuditAsyncClient, transports.AuditGrpcAsyncIOTransport, "grpc_asyncio"), + (AuditClient, transports.AuditRestTransport, "rest"), + ], +) +@mock.patch.object( + AuditClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuditClient), +) +@mock.patch.object( + AuditAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuditAsyncClient), +) +def test_audit_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(AuditClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(AuditClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (AuditClient, transports.AuditGrpcTransport, "grpc", "true"), + ( + AuditAsyncClient, + transports.AuditGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (AuditClient, transports.AuditGrpcTransport, "grpc", "false"), + ( + AuditAsyncClient, + transports.AuditGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + (AuditClient, transports.AuditRestTransport, "rest", "true"), + (AuditClient, transports.AuditRestTransport, "rest", "false"), + ], +) +@mock.patch.object( + AuditClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuditClient), +) +@mock.patch.object( + AuditAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuditAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_audit_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [AuditClient, AuditAsyncClient]) +@mock.patch.object( + AuditClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AuditClient) +) +@mock.patch.object( + AuditAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(AuditAsyncClient) +) +def test_audit_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [AuditClient, AuditAsyncClient]) +@mock.patch.object( + AuditClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuditClient), +) +@mock.patch.object( + AuditAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AuditAsyncClient), +) +def test_audit_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = AuditClient._DEFAULT_UNIVERSE + default_endpoint = AuditClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = AuditClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (AuditClient, transports.AuditGrpcTransport, "grpc"), + (AuditAsyncClient, transports.AuditGrpcAsyncIOTransport, "grpc_asyncio"), + (AuditClient, transports.AuditRestTransport, "rest"), + ], +) +def test_audit_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + (AuditClient, transports.AuditGrpcTransport, "grpc", grpc_helpers), + ( + AuditAsyncClient, + transports.AuditGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + (AuditClient, transports.AuditRestTransport, "rest", None), + ], +) +def test_audit_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_audit_client_client_options_from_dict(): + with mock.patch( + "google.cloud.cloudsecuritycompliance_v1.services.audit.transports.AuditGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = AuditClient(client_options={"api_endpoint": "squid.clam.whelk"}) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + (AuditClient, transports.AuditGrpcTransport, "grpc", grpc_helpers), + ( + AuditAsyncClient, + transports.AuditGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_audit_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "cloudsecuritycompliance.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=None, + default_host="cloudsecuritycompliance.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + audit.GenerateFrameworkAuditScopeReportRequest, + dict, + ], +) +def test_generate_framework_audit_scope_report(request_type, transport: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.generate_framework_audit_scope_report), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = audit.GenerateFrameworkAuditScopeReportResponse( + name="name_value", + compliance_framework="compliance_framework_value", + scope_report_contents=b"scope_report_contents_blob", + ) + response = client.generate_framework_audit_scope_report(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = audit.GenerateFrameworkAuditScopeReportRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, audit.GenerateFrameworkAuditScopeReportResponse) + assert response.name == "name_value" + assert response.compliance_framework == "compliance_framework_value" + + +def test_generate_framework_audit_scope_report_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = audit.GenerateFrameworkAuditScopeReportRequest( + scope="scope_value", + compliance_framework="compliance_framework_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.generate_framework_audit_scope_report), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.generate_framework_audit_scope_report(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == audit.GenerateFrameworkAuditScopeReportRequest( + scope="scope_value", + compliance_framework="compliance_framework_value", + ) + + +def test_generate_framework_audit_scope_report_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.generate_framework_audit_scope_report + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.generate_framework_audit_scope_report + ] = mock_rpc + request = {} + client.generate_framework_audit_scope_report(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.generate_framework_audit_scope_report(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_generate_framework_audit_scope_report_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.generate_framework_audit_scope_report + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.generate_framework_audit_scope_report + ] = mock_rpc + + request = {} + await client.generate_framework_audit_scope_report(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.generate_framework_audit_scope_report(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_generate_framework_audit_scope_report_async( + transport: str = "grpc_asyncio", + request_type=audit.GenerateFrameworkAuditScopeReportRequest, +): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + 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.generate_framework_audit_scope_report), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.GenerateFrameworkAuditScopeReportResponse( + name="name_value", + compliance_framework="compliance_framework_value", + ) + ) + response = await client.generate_framework_audit_scope_report(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = audit.GenerateFrameworkAuditScopeReportRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, audit.GenerateFrameworkAuditScopeReportResponse) + assert response.name == "name_value" + assert response.compliance_framework == "compliance_framework_value" + + +@pytest.mark.asyncio +async def test_generate_framework_audit_scope_report_async_from_dict(): + await test_generate_framework_audit_scope_report_async(request_type=dict) + + +def test_generate_framework_audit_scope_report_field_headers(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = audit.GenerateFrameworkAuditScopeReportRequest() + + request.scope = "scope_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.generate_framework_audit_scope_report), "__call__" + ) as call: + call.return_value = audit.GenerateFrameworkAuditScopeReportResponse() + client.generate_framework_audit_scope_report(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", + "scope=scope_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_generate_framework_audit_scope_report_field_headers_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = audit.GenerateFrameworkAuditScopeReportRequest() + + request.scope = "scope_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.generate_framework_audit_scope_report), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.GenerateFrameworkAuditScopeReportResponse() + ) + await client.generate_framework_audit_scope_report(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", + "scope=scope_value", + ) in kw["metadata"] + + +def test_generate_framework_audit_scope_report_flattened(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.generate_framework_audit_scope_report), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = audit.GenerateFrameworkAuditScopeReportResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.generate_framework_audit_scope_report( + scope="scope_value", + report_format=audit.GenerateFrameworkAuditScopeReportRequest.Format.ODF, + compliance_framework="compliance_framework_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].scope + mock_val = "scope_value" + assert arg == mock_val + arg = args[0].report_format + mock_val = audit.GenerateFrameworkAuditScopeReportRequest.Format.ODF + assert arg == mock_val + arg = args[0].compliance_framework + mock_val = "compliance_framework_value" + assert arg == mock_val + + +def test_generate_framework_audit_scope_report_flattened_error(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.generate_framework_audit_scope_report( + audit.GenerateFrameworkAuditScopeReportRequest(), + scope="scope_value", + report_format=audit.GenerateFrameworkAuditScopeReportRequest.Format.ODF, + compliance_framework="compliance_framework_value", + ) + + +@pytest.mark.asyncio +async def test_generate_framework_audit_scope_report_flattened_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.generate_framework_audit_scope_report), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = audit.GenerateFrameworkAuditScopeReportResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.GenerateFrameworkAuditScopeReportResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.generate_framework_audit_scope_report( + scope="scope_value", + report_format=audit.GenerateFrameworkAuditScopeReportRequest.Format.ODF, + compliance_framework="compliance_framework_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].scope + mock_val = "scope_value" + assert arg == mock_val + arg = args[0].report_format + mock_val = audit.GenerateFrameworkAuditScopeReportRequest.Format.ODF + assert arg == mock_val + arg = args[0].compliance_framework + mock_val = "compliance_framework_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_generate_framework_audit_scope_report_flattened_error_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.generate_framework_audit_scope_report( + audit.GenerateFrameworkAuditScopeReportRequest(), + scope="scope_value", + report_format=audit.GenerateFrameworkAuditScopeReportRequest.Format.ODF, + compliance_framework="compliance_framework_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + audit.CreateFrameworkAuditRequest, + dict, + ], +) +def test_create_framework_audit(request_type, transport: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_framework_audit), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = audit.CreateFrameworkAuditRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_framework_audit_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = audit.CreateFrameworkAuditRequest( + parent="parent_value", + framework_audit_id="framework_audit_id_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_framework_audit), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.create_framework_audit(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == audit.CreateFrameworkAuditRequest( + parent="parent_value", + framework_audit_id="framework_audit_id_value", + ) + + +def test_create_framework_audit_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_framework_audit + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_framework_audit + ] = mock_rpc + request = {} + client.create_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_framework_audit(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_create_framework_audit_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.create_framework_audit + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.create_framework_audit + ] = mock_rpc + + request = {} + await client.create_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.create_framework_audit(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_create_framework_audit_async( + transport: str = "grpc_asyncio", request_type=audit.CreateFrameworkAuditRequest +): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_framework_audit), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = audit.CreateFrameworkAuditRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_framework_audit_async_from_dict(): + await test_create_framework_audit_async(request_type=dict) + + +def test_create_framework_audit_field_headers(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = audit.CreateFrameworkAuditRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_framework_audit), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_framework_audit_field_headers_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = audit.CreateFrameworkAuditRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_framework_audit), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.create_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_create_framework_audit_flattened(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_framework_audit), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_framework_audit( + parent="parent_value", + framework_audit=audit.FrameworkAudit(name="name_value"), + framework_audit_id="framework_audit_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].framework_audit + mock_val = audit.FrameworkAudit(name="name_value") + assert arg == mock_val + arg = args[0].framework_audit_id + mock_val = "framework_audit_id_value" + assert arg == mock_val + + +def test_create_framework_audit_flattened_error(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_framework_audit( + audit.CreateFrameworkAuditRequest(), + parent="parent_value", + framework_audit=audit.FrameworkAudit(name="name_value"), + framework_audit_id="framework_audit_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_framework_audit_flattened_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_framework_audit), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_framework_audit( + parent="parent_value", + framework_audit=audit.FrameworkAudit(name="name_value"), + framework_audit_id="framework_audit_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].framework_audit + mock_val = audit.FrameworkAudit(name="name_value") + assert arg == mock_val + arg = args[0].framework_audit_id + mock_val = "framework_audit_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_framework_audit_flattened_error_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_framework_audit( + audit.CreateFrameworkAuditRequest(), + parent="parent_value", + framework_audit=audit.FrameworkAudit(name="name_value"), + framework_audit_id="framework_audit_id_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + audit.ListFrameworkAuditsRequest, + dict, + ], +) +def test_list_framework_audits(request_type, transport: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = audit.ListFrameworkAuditsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_framework_audits(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = audit.ListFrameworkAuditsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListFrameworkAuditsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_framework_audits_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = audit.ListFrameworkAuditsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_framework_audits(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == audit.ListFrameworkAuditsRequest( + parent="parent_value", + page_token="page_token_value", + filter="filter_value", + ) + + +def test_list_framework_audits_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_framework_audits + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_framework_audits + ] = mock_rpc + request = {} + client.list_framework_audits(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_framework_audits(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_framework_audits_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.list_framework_audits + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_framework_audits + ] = mock_rpc + + request = {} + await client.list_framework_audits(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_framework_audits(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_framework_audits_async( + transport: str = "grpc_asyncio", request_type=audit.ListFrameworkAuditsRequest +): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.ListFrameworkAuditsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_framework_audits(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = audit.ListFrameworkAuditsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListFrameworkAuditsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_framework_audits_async_from_dict(): + await test_list_framework_audits_async(request_type=dict) + + +def test_list_framework_audits_field_headers(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = audit.ListFrameworkAuditsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + call.return_value = audit.ListFrameworkAuditsResponse() + client.list_framework_audits(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_framework_audits_field_headers_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = audit.ListFrameworkAuditsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.ListFrameworkAuditsResponse() + ) + await client.list_framework_audits(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_framework_audits_flattened(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = audit.ListFrameworkAuditsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_framework_audits( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_framework_audits_flattened_error(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_framework_audits( + audit.ListFrameworkAuditsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_framework_audits_flattened_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = audit.ListFrameworkAuditsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.ListFrameworkAuditsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_framework_audits( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_framework_audits_flattened_error_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_framework_audits( + audit.ListFrameworkAuditsRequest(), + parent="parent_value", + ) + + +def test_list_framework_audits_pager(transport_name: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + audit.FrameworkAudit(), + audit.FrameworkAudit(), + ], + next_page_token="abc", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[], + next_page_token="def", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + ], + next_page_token="ghi", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + audit.FrameworkAudit(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_framework_audits(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, audit.FrameworkAudit) for i in results) + + +def test_list_framework_audits_pages(transport_name: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + audit.FrameworkAudit(), + audit.FrameworkAudit(), + ], + next_page_token="abc", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[], + next_page_token="def", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + ], + next_page_token="ghi", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + audit.FrameworkAudit(), + ], + ), + RuntimeError, + ) + pages = list(client.list_framework_audits(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_framework_audits_async_pager(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + audit.FrameworkAudit(), + audit.FrameworkAudit(), + ], + next_page_token="abc", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[], + next_page_token="def", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + ], + next_page_token="ghi", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + audit.FrameworkAudit(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_framework_audits( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, audit.FrameworkAudit) for i in responses) + + +@pytest.mark.asyncio +async def test_list_framework_audits_async_pages(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + audit.FrameworkAudit(), + audit.FrameworkAudit(), + ], + next_page_token="abc", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[], + next_page_token="def", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + ], + next_page_token="ghi", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + audit.FrameworkAudit(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_framework_audits(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + audit.GetFrameworkAuditRequest, + dict, + ], +) +def test_get_framework_audit(request_type, transport: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_framework_audit), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = audit.FrameworkAudit( + name="name_value", + framework_audit_id="framework_audit_id_value", + compliance_framework="compliance_framework_value", + scope="scope_value", + compliance_state=audit.ComplianceState.COMPLIANT, + operation_id="operation_id_value", + state=audit.FrameworkAudit.State.SCHEDULED, + ) + response = client.get_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = audit.GetFrameworkAuditRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, audit.FrameworkAudit) + assert response.name == "name_value" + assert response.framework_audit_id == "framework_audit_id_value" + assert response.compliance_framework == "compliance_framework_value" + assert response.scope == "scope_value" + assert response.compliance_state == audit.ComplianceState.COMPLIANT + assert response.operation_id == "operation_id_value" + assert response.state == audit.FrameworkAudit.State.SCHEDULED + + +def test_get_framework_audit_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = audit.GetFrameworkAuditRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_framework_audit), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_framework_audit(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == audit.GetFrameworkAuditRequest( + name="name_value", + ) + + +def test_get_framework_audit_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_framework_audit in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_framework_audit + ] = mock_rpc + request = {} + client.get_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_framework_audit(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_framework_audit_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.get_framework_audit + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_framework_audit + ] = mock_rpc + + request = {} + await client.get_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_framework_audit(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_framework_audit_async( + transport: str = "grpc_asyncio", request_type=audit.GetFrameworkAuditRequest +): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_framework_audit), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.FrameworkAudit( + name="name_value", + framework_audit_id="framework_audit_id_value", + compliance_framework="compliance_framework_value", + scope="scope_value", + compliance_state=audit.ComplianceState.COMPLIANT, + operation_id="operation_id_value", + state=audit.FrameworkAudit.State.SCHEDULED, + ) + ) + response = await client.get_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = audit.GetFrameworkAuditRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, audit.FrameworkAudit) + assert response.name == "name_value" + assert response.framework_audit_id == "framework_audit_id_value" + assert response.compliance_framework == "compliance_framework_value" + assert response.scope == "scope_value" + assert response.compliance_state == audit.ComplianceState.COMPLIANT + assert response.operation_id == "operation_id_value" + assert response.state == audit.FrameworkAudit.State.SCHEDULED + + +@pytest.mark.asyncio +async def test_get_framework_audit_async_from_dict(): + await test_get_framework_audit_async(request_type=dict) + + +def test_get_framework_audit_field_headers(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = audit.GetFrameworkAuditRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_framework_audit), "__call__" + ) as call: + call.return_value = audit.FrameworkAudit() + client.get_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_framework_audit_field_headers_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = audit.GetFrameworkAuditRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_framework_audit), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.FrameworkAudit() + ) + await client.get_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_framework_audit_flattened(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_framework_audit), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = audit.FrameworkAudit() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_framework_audit( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_framework_audit_flattened_error(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_framework_audit( + audit.GetFrameworkAuditRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_framework_audit_flattened_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_framework_audit), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = audit.FrameworkAudit() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.FrameworkAudit() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_framework_audit( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_framework_audit_flattened_error_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_framework_audit( + audit.GetFrameworkAuditRequest(), + name="name_value", + ) + + +def test_generate_framework_audit_scope_report_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.generate_framework_audit_scope_report + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.generate_framework_audit_scope_report + ] = mock_rpc + + request = {} + client.generate_framework_audit_scope_report(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.generate_framework_audit_scope_report(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_generate_framework_audit_scope_report_rest_required_fields( + request_type=audit.GenerateFrameworkAuditScopeReportRequest, +): + transport_class = transports.AuditRestTransport + + request_init = {} + request_init["scope"] = "" + request_init["compliance_framework"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).generate_framework_audit_scope_report._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["scope"] = "scope_value" + jsonified_request["complianceFramework"] = "compliance_framework_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).generate_framework_audit_scope_report._get_unset_required_fields( + jsonified_request + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "scope" in jsonified_request + assert jsonified_request["scope"] == "scope_value" + assert "complianceFramework" in jsonified_request + assert jsonified_request["complianceFramework"] == "compliance_framework_value" + + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = audit.GenerateFrameworkAuditScopeReportResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = audit.GenerateFrameworkAuditScopeReportResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.generate_framework_audit_scope_report(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_generate_framework_audit_scope_report_rest_unset_required_fields(): + transport = transports.AuditRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.generate_framework_audit_scope_report._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set(()) + & set( + ( + "scope", + "reportFormat", + "complianceFramework", + ) + ) + ) + + +def test_generate_framework_audit_scope_report_rest_flattened(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = audit.GenerateFrameworkAuditScopeReportResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"scope": "folders/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + scope="scope_value", + report_format=audit.GenerateFrameworkAuditScopeReportRequest.Format.ODF, + compliance_framework="compliance_framework_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = audit.GenerateFrameworkAuditScopeReportResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.generate_framework_audit_scope_report(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{scope=folders/*/locations/*}/frameworkAuditScopeReports:generateFrameworkAuditScopeReport" + % client.transport._host, + args[1], + ) + + +def test_generate_framework_audit_scope_report_rest_flattened_error( + transport: str = "rest", +): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.generate_framework_audit_scope_report( + audit.GenerateFrameworkAuditScopeReportRequest(), + scope="scope_value", + report_format=audit.GenerateFrameworkAuditScopeReportRequest.Format.ODF, + compliance_framework="compliance_framework_value", + ) + + +def test_create_framework_audit_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_framework_audit + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_framework_audit + ] = mock_rpc + + request = {} + client.create_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_framework_audit(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_framework_audit_rest_required_fields( + request_type=audit.CreateFrameworkAuditRequest, +): + transport_class = transports.AuditRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_framework_audit._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_framework_audit._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("framework_audit_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_framework_audit(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_framework_audit_rest_unset_required_fields(): + transport = transports.AuditRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_framework_audit._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("frameworkAuditId",)) + & set( + ( + "parent", + "frameworkAudit", + ) + ) + ) + + +def test_create_framework_audit_rest_flattened(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + framework_audit=audit.FrameworkAudit(name="name_value"), + framework_audit_id="framework_audit_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_framework_audit(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=organizations/*/locations/*}/frameworkAudits" + % client.transport._host, + args[1], + ) + + +def test_create_framework_audit_rest_flattened_error(transport: str = "rest"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_framework_audit( + audit.CreateFrameworkAuditRequest(), + parent="parent_value", + framework_audit=audit.FrameworkAudit(name="name_value"), + framework_audit_id="framework_audit_id_value", + ) + + +def test_list_framework_audits_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_framework_audits + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_framework_audits + ] = mock_rpc + + request = {} + client.list_framework_audits(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_framework_audits(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_framework_audits_rest_required_fields( + request_type=audit.ListFrameworkAuditsRequest, +): + transport_class = transports.AuditRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_framework_audits._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_framework_audits._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = audit.ListFrameworkAuditsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = audit.ListFrameworkAuditsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_framework_audits(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_framework_audits_rest_unset_required_fields(): + transport = transports.AuditRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_framework_audits._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_framework_audits_rest_flattened(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = audit.ListFrameworkAuditsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "organizations/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = audit.ListFrameworkAuditsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_framework_audits(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=organizations/*/locations/*}/frameworkAudits" + % client.transport._host, + args[1], + ) + + +def test_list_framework_audits_rest_flattened_error(transport: str = "rest"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_framework_audits( + audit.ListFrameworkAuditsRequest(), + parent="parent_value", + ) + + +def test_list_framework_audits_rest_pager(transport: str = "rest"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + audit.FrameworkAudit(), + audit.FrameworkAudit(), + ], + next_page_token="abc", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[], + next_page_token="def", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + ], + next_page_token="ghi", + ), + audit.ListFrameworkAuditsResponse( + framework_audits=[ + audit.FrameworkAudit(), + audit.FrameworkAudit(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(audit.ListFrameworkAuditsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "organizations/sample1/locations/sample2"} + + pager = client.list_framework_audits(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, audit.FrameworkAudit) for i in results) + + pages = list(client.list_framework_audits(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_get_framework_audit_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_framework_audit in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_framework_audit + ] = mock_rpc + + request = {} + client.get_framework_audit(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_framework_audit(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_framework_audit_rest_required_fields( + request_type=audit.GetFrameworkAuditRequest, +): + transport_class = transports.AuditRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_framework_audit._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_framework_audit._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = audit.FrameworkAudit() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = audit.FrameworkAudit.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_framework_audit(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_framework_audit_rest_unset_required_fields(): + transport = transports.AuditRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_framework_audit._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_framework_audit_rest_flattened(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = audit.FrameworkAudit() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "organizations/sample1/locations/sample2/frameworkAudits/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = audit.FrameworkAudit.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_framework_audit(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=organizations/*/locations/*/frameworkAudits/*}" + % client.transport._host, + args[1], + ) + + +def test_get_framework_audit_rest_flattened_error(transport: str = "rest"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_framework_audit( + audit.GetFrameworkAuditRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.AuditGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.AuditGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AuditClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.AuditGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AuditClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AuditClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.AuditGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AuditClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.AuditGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = AuditClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.AuditGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.AuditGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AuditGrpcTransport, + transports.AuditGrpcAsyncIOTransport, + transports.AuditRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = AuditClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_generate_framework_audit_scope_report_empty_call_grpc(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.generate_framework_audit_scope_report), "__call__" + ) as call: + call.return_value = audit.GenerateFrameworkAuditScopeReportResponse() + client.generate_framework_audit_scope_report(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.GenerateFrameworkAuditScopeReportRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_framework_audit_empty_call_grpc(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_framework_audit), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_framework_audit(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.CreateFrameworkAuditRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_framework_audits_empty_call_grpc(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + call.return_value = audit.ListFrameworkAuditsResponse() + client.list_framework_audits(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.ListFrameworkAuditsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_framework_audit_empty_call_grpc(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_framework_audit), "__call__" + ) as call: + call.return_value = audit.FrameworkAudit() + client.get_framework_audit(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.GetFrameworkAuditRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = AuditAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_generate_framework_audit_scope_report_empty_call_grpc_asyncio(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.generate_framework_audit_scope_report), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.GenerateFrameworkAuditScopeReportResponse( + name="name_value", + compliance_framework="compliance_framework_value", + ) + ) + await client.generate_framework_audit_scope_report(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.GenerateFrameworkAuditScopeReportRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_framework_audit_empty_call_grpc_asyncio(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_framework_audit), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_framework_audit(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.CreateFrameworkAuditRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_framework_audits_empty_call_grpc_asyncio(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.ListFrameworkAuditsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_framework_audits(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.ListFrameworkAuditsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_framework_audit_empty_call_grpc_asyncio(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_framework_audit), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + audit.FrameworkAudit( + name="name_value", + framework_audit_id="framework_audit_id_value", + compliance_framework="compliance_framework_value", + scope="scope_value", + compliance_state=audit.ComplianceState.COMPLIANT, + operation_id="operation_id_value", + state=audit.FrameworkAudit.State.SCHEDULED, + ) + ) + await client.get_framework_audit(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.GetFrameworkAuditRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = AuditClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_generate_framework_audit_scope_report_rest_bad_request( + request_type=audit.GenerateFrameworkAuditScopeReportRequest, +): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"scope": "folders/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.generate_framework_audit_scope_report(request) + + +@pytest.mark.parametrize( + "request_type", + [ + audit.GenerateFrameworkAuditScopeReportRequest, + dict, + ], +) +def test_generate_framework_audit_scope_report_rest_call_success(request_type): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"scope": "folders/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = audit.GenerateFrameworkAuditScopeReportResponse( + name="name_value", + compliance_framework="compliance_framework_value", + scope_report_contents=b"scope_report_contents_blob", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = audit.GenerateFrameworkAuditScopeReportResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.generate_framework_audit_scope_report(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, audit.GenerateFrameworkAuditScopeReportResponse) + assert response.name == "name_value" + assert response.compliance_framework == "compliance_framework_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_generate_framework_audit_scope_report_rest_interceptors(null_interceptor): + transport = transports.AuditRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.AuditRestInterceptor(), + ) + client = AuditClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AuditRestInterceptor, "post_generate_framework_audit_scope_report" + ) as post, mock.patch.object( + transports.AuditRestInterceptor, + "post_generate_framework_audit_scope_report_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.AuditRestInterceptor, "pre_generate_framework_audit_scope_report" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = audit.GenerateFrameworkAuditScopeReportRequest.pb( + audit.GenerateFrameworkAuditScopeReportRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = audit.GenerateFrameworkAuditScopeReportResponse.to_json( + audit.GenerateFrameworkAuditScopeReportResponse() + ) + req.return_value.content = return_value + + request = audit.GenerateFrameworkAuditScopeReportRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = audit.GenerateFrameworkAuditScopeReportResponse() + post_with_metadata.return_value = ( + audit.GenerateFrameworkAuditScopeReportResponse(), + metadata, + ) + + client.generate_framework_audit_scope_report( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_framework_audit_rest_bad_request( + request_type=audit.CreateFrameworkAuditRequest, +): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_framework_audit(request) + + +@pytest.mark.parametrize( + "request_type", + [ + audit.CreateFrameworkAuditRequest, + dict, + ], +) +def test_create_framework_audit_rest_call_success(request_type): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request_init["framework_audit"] = { + "name": "name_value", + "framework_audit_id": "framework_audit_id_value", + "compliance_framework": "compliance_framework_value", + "scope": "scope_value", + "framework_audit_destination": { + "bucket": {"bucket_uri": "bucket_uri_value", "framework_audit_format": 1} + }, + "start_time": {"seconds": 751, "nanos": 543}, + "finish_time": {}, + "compliance_state": 1, + "report_summary": { + "total_count": 1196, + "compliant_count": 1615, + "violation_count": 1629, + "manual_review_needed_count": 2747, + "error_count": 1202, + }, + "cloud_control_group_audit_details": [ + { + "cloud_control_group_id": "cloud_control_group_id_value", + "display_name": "display_name_value", + "description": "description_value", + "responsibility_type": "responsibility_type_value", + "google_responsibility_description": "google_responsibility_description_value", + "google_responsibility_implementation": "google_responsibility_implementation_value", + "customer_responsibility_description": "customer_responsibility_description_value", + "customer_responsibility_implementation": "customer_responsibility_implementation_value", + "compliance_state": 1, + "control_id": "control_id_value", + "control_family": { + "family_id": "family_id_value", + "display_name": "display_name_value", + }, + "cloud_control_details": [ + { + "cloud_control": "cloud_control_value", + "cloud_control_id": "cloud_control_id_value", + "cloud_control_description": "cloud_control_description_value", + "compliance_state": 1, + "report_summary": {}, + "findings": [ + { + "name": "name_value", + "compliance_state": 1, + "observation": { + "current_value": "current_value_value", + "expected_value": "expected_value_value", + "guidance": "guidance_value", + }, + "evidence": { + "resource": "resource_value", + "service": "service_value", + "evidence_path": "evidence_path_value", + }, + } + ], + } + ], + "report_summary": {}, + } + ], + "cloud_control_audit_details": {}, + "operation_id": "operation_id_value", + "state": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = audit.CreateFrameworkAuditRequest.meta.fields["framework_audit"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["framework_audit"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["framework_audit"][field])): + del request_init["framework_audit"][field][i][subfield] + else: + del request_init["framework_audit"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_framework_audit(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_framework_audit_rest_interceptors(null_interceptor): + transport = transports.AuditRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.AuditRestInterceptor(), + ) + client = AuditClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.AuditRestInterceptor, "post_create_framework_audit" + ) as post, mock.patch.object( + transports.AuditRestInterceptor, "post_create_framework_audit_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.AuditRestInterceptor, "pre_create_framework_audit" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = audit.CreateFrameworkAuditRequest.pb( + audit.CreateFrameworkAuditRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = audit.CreateFrameworkAuditRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.create_framework_audit( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_framework_audits_rest_bad_request( + request_type=audit.ListFrameworkAuditsRequest, +): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_framework_audits(request) + + +@pytest.mark.parametrize( + "request_type", + [ + audit.ListFrameworkAuditsRequest, + dict, + ], +) +def test_list_framework_audits_rest_call_success(request_type): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = audit.ListFrameworkAuditsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = audit.ListFrameworkAuditsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_framework_audits(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListFrameworkAuditsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_framework_audits_rest_interceptors(null_interceptor): + transport = transports.AuditRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.AuditRestInterceptor(), + ) + client = AuditClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AuditRestInterceptor, "post_list_framework_audits" + ) as post, mock.patch.object( + transports.AuditRestInterceptor, "post_list_framework_audits_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.AuditRestInterceptor, "pre_list_framework_audits" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = audit.ListFrameworkAuditsRequest.pb( + audit.ListFrameworkAuditsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = audit.ListFrameworkAuditsResponse.to_json( + audit.ListFrameworkAuditsResponse() + ) + req.return_value.content = return_value + + request = audit.ListFrameworkAuditsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = audit.ListFrameworkAuditsResponse() + post_with_metadata.return_value = audit.ListFrameworkAuditsResponse(), metadata + + client.list_framework_audits( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_framework_audit_rest_bad_request( + request_type=audit.GetFrameworkAuditRequest, +): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/locations/sample2/frameworkAudits/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_framework_audit(request) + + +@pytest.mark.parametrize( + "request_type", + [ + audit.GetFrameworkAuditRequest, + dict, + ], +) +def test_get_framework_audit_rest_call_success(request_type): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "organizations/sample1/locations/sample2/frameworkAudits/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = audit.FrameworkAudit( + name="name_value", + framework_audit_id="framework_audit_id_value", + compliance_framework="compliance_framework_value", + scope="scope_value", + compliance_state=audit.ComplianceState.COMPLIANT, + operation_id="operation_id_value", + state=audit.FrameworkAudit.State.SCHEDULED, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = audit.FrameworkAudit.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_framework_audit(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, audit.FrameworkAudit) + assert response.name == "name_value" + assert response.framework_audit_id == "framework_audit_id_value" + assert response.compliance_framework == "compliance_framework_value" + assert response.scope == "scope_value" + assert response.compliance_state == audit.ComplianceState.COMPLIANT + assert response.operation_id == "operation_id_value" + assert response.state == audit.FrameworkAudit.State.SCHEDULED + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_framework_audit_rest_interceptors(null_interceptor): + transport = transports.AuditRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.AuditRestInterceptor(), + ) + client = AuditClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AuditRestInterceptor, "post_get_framework_audit" + ) as post, mock.patch.object( + transports.AuditRestInterceptor, "post_get_framework_audit_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.AuditRestInterceptor, "pre_get_framework_audit" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = audit.GetFrameworkAuditRequest.pb(audit.GetFrameworkAuditRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = audit.FrameworkAudit.to_json(audit.FrameworkAudit()) + req.return_value.content = return_value + + request = audit.GetFrameworkAuditRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = audit.FrameworkAudit() + post_with_metadata.return_value = audit.FrameworkAudit(), metadata + + client.get_framework_audit( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_location(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.GetLocationRequest, + dict, + ], +) +def test_get_location_rest(request_type): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = locations_pb2.Location() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_location(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_list_locations_rest_bad_request( + request_type=locations_pb2.ListLocationsRequest, +): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict({"name": "organizations/sample1"}, request) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_locations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.ListLocationsRequest, + dict, + ], +) +def test_list_locations_rest(request_type): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "organizations/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = locations_pb2.ListLocationsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_locations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_cancel_operation_rest_bad_request( + request_type=operations_pb2.CancelOperationRequest, +): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.cancel_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.CancelOperationRequest, + dict, + ], +) +def test_cancel_operation_rest(request_type): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = { + "name": "organizations/sample1/locations/sample2/operations/sample3" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "{}" + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.cancel_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_rest_bad_request( + request_type=operations_pb2.DeleteOperationRequest, +): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.DeleteOperationRequest, + dict, + ], +) +def test_delete_operation_rest(request_type): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = { + "name": "organizations/sample1/locations/sample2/operations/sample3" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "{}" + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = { + "name": "organizations/sample1/locations/sample2/operations/sample3" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + request_type=operations_pb2.ListOperationsRequest, +): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_initialize_client_w_rest(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_generate_framework_audit_scope_report_empty_call_rest(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.generate_framework_audit_scope_report), "__call__" + ) as call: + client.generate_framework_audit_scope_report(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.GenerateFrameworkAuditScopeReportRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_framework_audit_empty_call_rest(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_framework_audit), "__call__" + ) as call: + client.create_framework_audit(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.CreateFrameworkAuditRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_framework_audits_empty_call_rest(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_framework_audits), "__call__" + ) as call: + client.list_framework_audits(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.ListFrameworkAuditsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_framework_audit_empty_call_rest(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_framework_audit), "__call__" + ) as call: + client.get_framework_audit(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audit.GetFrameworkAuditRequest() + + assert args[0] == request_msg + + +def test_audit_rest_lro_client(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have an api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.AuditGrpcTransport, + ) + + +def test_audit_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.AuditTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_audit_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.cloudsecuritycompliance_v1.services.audit.transports.AuditTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.AuditTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "generate_framework_audit_scope_report", + "create_framework_audit", + "list_framework_audits", + "get_framework_audit", + "get_location", + "list_locations", + "get_operation", + "cancel_operation", + "delete_operation", + "list_operations", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_audit_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.cloudsecuritycompliance_v1.services.audit.transports.AuditTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.AuditTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_audit_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.cloud.cloudsecuritycompliance_v1.services.audit.transports.AuditTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.AuditTransport() + adc.assert_called_once() + + +def test_audit_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + AuditClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AuditGrpcTransport, + transports.AuditGrpcAsyncIOTransport, + ], +) +def test_audit_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AuditGrpcTransport, + transports.AuditGrpcAsyncIOTransport, + transports.AuditRestTransport, + ], +) +def test_audit_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.AuditGrpcTransport, grpc_helpers), + (transports.AuditGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_audit_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "cloudsecuritycompliance.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="cloudsecuritycompliance.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [transports.AuditGrpcTransport, transports.AuditGrpcAsyncIOTransport], +) +def test_audit_grpc_transport_client_cert_source_for_mtls(transport_class): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + +def test_audit_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.AuditRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_audit_host_no_port(transport_name): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="cloudsecuritycompliance.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "cloudsecuritycompliance.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://cloudsecuritycompliance.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_audit_host_with_port(transport_name): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="cloudsecuritycompliance.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "cloudsecuritycompliance.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://cloudsecuritycompliance.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_audit_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = AuditClient( + credentials=creds1, + transport=transport_name, + ) + client2 = AuditClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.generate_framework_audit_scope_report._session + session2 = client2.transport.generate_framework_audit_scope_report._session + assert session1 != session2 + session1 = client1.transport.create_framework_audit._session + session2 = client2.transport.create_framework_audit._session + assert session1 != session2 + session1 = client1.transport.list_framework_audits._session + session2 = client2.transport.list_framework_audits._session + assert session1 != session2 + session1 = client1.transport.get_framework_audit._session + session2 = client2.transport.get_framework_audit._session + assert session1 != session2 + + +def test_audit_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.AuditGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_audit_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.AuditGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [transports.AuditGrpcTransport, transports.AuditGrpcAsyncIOTransport], +) +def test_audit_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [transports.AuditGrpcTransport, transports.AuditGrpcAsyncIOTransport], +) +def test_audit_transport_channel_mtls_with_adc(transport_class): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_audit_grpc_lro_client(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_audit_grpc_lro_async_client(): + client = AuditAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_framework_audit_path(): + project = "squid" + location = "clam" + framework_audit = "whelk" + expected = "projects/{project}/locations/{location}/frameworkAudits/{framework_audit}".format( + project=project, + location=location, + framework_audit=framework_audit, + ) + actual = AuditClient.framework_audit_path(project, location, framework_audit) + assert expected == actual + + +def test_parse_framework_audit_path(): + expected = { + "project": "octopus", + "location": "oyster", + "framework_audit": "nudibranch", + } + path = AuditClient.framework_audit_path(**expected) + + # Check that the path construction is reversible. + actual = AuditClient.parse_framework_audit_path(path) + assert expected == actual + + +def test_generate_framework_audit_scope_report_response_path(): + project = "cuttlefish" + location = "mussel" + generate_framework_audit_scope_report_response = "winkle" + expected = "projects/{project}/locations/{location}/frameworkAuditScopeReports/{generate_framework_audit_scope_report_response}".format( + project=project, + location=location, + generate_framework_audit_scope_report_response=generate_framework_audit_scope_report_response, + ) + actual = AuditClient.generate_framework_audit_scope_report_response_path( + project, location, generate_framework_audit_scope_report_response + ) + assert expected == actual + + +def test_parse_generate_framework_audit_scope_report_response_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "generate_framework_audit_scope_report_response": "abalone", + } + path = AuditClient.generate_framework_audit_scope_report_response_path(**expected) + + # Check that the path construction is reversible. + actual = AuditClient.parse_generate_framework_audit_scope_report_response_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AuditClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = AuditClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AuditClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = AuditClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = AuditClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AuditClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = AuditClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = AuditClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AuditClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format( + project=project, + ) + actual = AuditClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = AuditClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AuditClient.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 = AuditClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = AuditClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AuditClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.AuditTransport, "_prep_wrapped_messages") as prep: + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.AuditTransport, "_prep_wrapped_messages") as prep: + transport_class = AuditClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_delete_operation(transport: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_operation_async(transport: str = "grpc_asyncio"): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_field_headers(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = None + + client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_operation_field_headers_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_delete_operation_from_dict(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_delete_operation_from_dict_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_cancel_operation(transport: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_cancel_operation_async(transport: str = "grpc_asyncio"): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_cancel_operation_field_headers(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = None + + client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_cancel_operation_field_headers_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_cancel_operation_from_dict(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_cancel_operation_from_dict_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_operation(transport: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc_asyncio"): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc_asyncio"): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_locations(transport: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + response = client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +@pytest.mark.asyncio +async def test_list_locations_async(transport: str = "grpc_asyncio"): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_list_locations_field_headers(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = locations_pb2.ListLocationsResponse() + + client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_locations_field_headers_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + await client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_locations_from_dict(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + + response = client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_locations_from_dict_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_location(transport: str = "grpc"): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + response = client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +@pytest.mark.asyncio +async def test_get_location_async(transport: str = "grpc_asyncio"): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_get_location_field_headers(): + client = AuditClient(credentials=ga_credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = locations_pb2.Location() + + client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations/abc", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_location_field_headers_async(): + client = AuditAsyncClient(credentials=async_anonymous_credentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + await client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations/abc", + ) in kw["metadata"] + + +def test_get_location_from_dict(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + + response = client.get_location( + request={ + "name": "locations/abc", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_location_from_dict_async(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close_grpc(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = AuditAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = AuditClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (AuditClient, transports.AuditGrpcTransport), + (AuditAsyncClient, transports.AuditGrpcAsyncIOTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-cloud-cloudsecuritycompliance/tests/unit/gapic/cloudsecuritycompliance_v1/test_cm_enrollment_service.py b/packages/google-cloud-cloudsecuritycompliance/tests/unit/gapic/cloudsecuritycompliance_v1/test_cm_enrollment_service.py new file mode 100644 index 000000000000..06d188d4e74c --- /dev/null +++ b/packages/google-cloud-cloudsecuritycompliance/tests/unit/gapic/cloudsecuritycompliance_v1/test_cm_enrollment_service.py @@ -0,0 +1,4795 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore + +from google.cloud.cloudsecuritycompliance_v1.services.cm_enrollment_service import ( + CmEnrollmentServiceAsyncClient, + CmEnrollmentServiceClient, + transports, +) +from google.cloud.cloudsecuritycompliance_v1.types import cm_enrollment_service + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert CmEnrollmentServiceClient._get_default_mtls_endpoint(None) is None + assert ( + CmEnrollmentServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + CmEnrollmentServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + CmEnrollmentServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + CmEnrollmentServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + CmEnrollmentServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert CmEnrollmentServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert CmEnrollmentServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert CmEnrollmentServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + CmEnrollmentServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert CmEnrollmentServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert CmEnrollmentServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert CmEnrollmentServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + CmEnrollmentServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert CmEnrollmentServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert CmEnrollmentServiceClient._get_client_cert_source(None, False) is None + assert ( + CmEnrollmentServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + CmEnrollmentServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + CmEnrollmentServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + CmEnrollmentServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + CmEnrollmentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmEnrollmentServiceClient), +) +@mock.patch.object( + CmEnrollmentServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmEnrollmentServiceAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = CmEnrollmentServiceClient._DEFAULT_UNIVERSE + default_endpoint = CmEnrollmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = CmEnrollmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + CmEnrollmentServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + CmEnrollmentServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == CmEnrollmentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CmEnrollmentServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + CmEnrollmentServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == CmEnrollmentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CmEnrollmentServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == CmEnrollmentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CmEnrollmentServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + CmEnrollmentServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + CmEnrollmentServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + CmEnrollmentServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + CmEnrollmentServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + CmEnrollmentServiceClient._get_universe_domain(None, None) + == CmEnrollmentServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + CmEnrollmentServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = CmEnrollmentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = CmEnrollmentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (CmEnrollmentServiceClient, "grpc"), + (CmEnrollmentServiceAsyncClient, "grpc_asyncio"), + (CmEnrollmentServiceClient, "rest"), + ], +) +def test_cm_enrollment_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "cloudsecuritycompliance.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://cloudsecuritycompliance.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.CmEnrollmentServiceGrpcTransport, "grpc"), + (transports.CmEnrollmentServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.CmEnrollmentServiceRestTransport, "rest"), + ], +) +def test_cm_enrollment_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (CmEnrollmentServiceClient, "grpc"), + (CmEnrollmentServiceAsyncClient, "grpc_asyncio"), + (CmEnrollmentServiceClient, "rest"), + ], +) +def test_cm_enrollment_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "cloudsecuritycompliance.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://cloudsecuritycompliance.googleapis.com" + ) + + +def test_cm_enrollment_service_client_get_transport_class(): + transport = CmEnrollmentServiceClient.get_transport_class() + available_transports = [ + transports.CmEnrollmentServiceGrpcTransport, + transports.CmEnrollmentServiceRestTransport, + ] + assert transport in available_transports + + transport = CmEnrollmentServiceClient.get_transport_class("grpc") + assert transport == transports.CmEnrollmentServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceGrpcTransport, + "grpc", + ), + ( + CmEnrollmentServiceAsyncClient, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + CmEnrollmentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmEnrollmentServiceClient), +) +@mock.patch.object( + CmEnrollmentServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmEnrollmentServiceAsyncClient), +) +def test_cm_enrollment_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(CmEnrollmentServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(CmEnrollmentServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceGrpcTransport, + "grpc", + "true", + ), + ( + CmEnrollmentServiceAsyncClient, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceGrpcTransport, + "grpc", + "false", + ), + ( + CmEnrollmentServiceAsyncClient, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceRestTransport, + "rest", + "true", + ), + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + CmEnrollmentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmEnrollmentServiceClient), +) +@mock.patch.object( + CmEnrollmentServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmEnrollmentServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_cm_enrollment_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", [CmEnrollmentServiceClient, CmEnrollmentServiceAsyncClient] +) +@mock.patch.object( + CmEnrollmentServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(CmEnrollmentServiceClient), +) +@mock.patch.object( + CmEnrollmentServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(CmEnrollmentServiceAsyncClient), +) +def test_cm_enrollment_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize( + "client_class", [CmEnrollmentServiceClient, CmEnrollmentServiceAsyncClient] +) +@mock.patch.object( + CmEnrollmentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmEnrollmentServiceClient), +) +@mock.patch.object( + CmEnrollmentServiceAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmEnrollmentServiceAsyncClient), +) +def test_cm_enrollment_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = CmEnrollmentServiceClient._DEFAULT_UNIVERSE + default_endpoint = CmEnrollmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = CmEnrollmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceGrpcTransport, + "grpc", + ), + ( + CmEnrollmentServiceAsyncClient, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceRestTransport, + "rest", + ), + ], +) +def test_cm_enrollment_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + CmEnrollmentServiceAsyncClient, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceRestTransport, + "rest", + None, + ), + ], +) +def test_cm_enrollment_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_cm_enrollment_service_client_client_options_from_dict(): + with mock.patch( + "google.cloud.cloudsecuritycompliance_v1.services.cm_enrollment_service.transports.CmEnrollmentServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = CmEnrollmentServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + CmEnrollmentServiceClient, + transports.CmEnrollmentServiceGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + CmEnrollmentServiceAsyncClient, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_cm_enrollment_service_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "cloudsecuritycompliance.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=None, + default_host="cloudsecuritycompliance.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + cm_enrollment_service.UpdateCmEnrollmentRequest, + dict, + ], +) +def test_update_cm_enrollment(request_type, transport: str = "grpc"): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_cm_enrollment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = cm_enrollment_service.CmEnrollment( + name="name_value", + enrolled=True, + ) + response = client.update_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = cm_enrollment_service.UpdateCmEnrollmentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, cm_enrollment_service.CmEnrollment) + assert response.name == "name_value" + assert response.enrolled is True + + +def test_update_cm_enrollment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = cm_enrollment_service.UpdateCmEnrollmentRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_cm_enrollment), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.update_cm_enrollment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == cm_enrollment_service.UpdateCmEnrollmentRequest() + + +def test_update_cm_enrollment_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.update_cm_enrollment in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_cm_enrollment + ] = mock_rpc + request = {} + client.update_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_cm_enrollment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_update_cm_enrollment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.update_cm_enrollment + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.update_cm_enrollment + ] = mock_rpc + + request = {} + await client.update_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.update_cm_enrollment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_update_cm_enrollment_async( + transport: str = "grpc_asyncio", + request_type=cm_enrollment_service.UpdateCmEnrollmentRequest, +): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_cm_enrollment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cm_enrollment_service.CmEnrollment( + name="name_value", + enrolled=True, + ) + ) + response = await client.update_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = cm_enrollment_service.UpdateCmEnrollmentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, cm_enrollment_service.CmEnrollment) + assert response.name == "name_value" + assert response.enrolled is True + + +@pytest.mark.asyncio +async def test_update_cm_enrollment_async_from_dict(): + await test_update_cm_enrollment_async(request_type=dict) + + +def test_update_cm_enrollment_field_headers(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cm_enrollment_service.UpdateCmEnrollmentRequest() + + request.cm_enrollment.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_cm_enrollment), "__call__" + ) as call: + call.return_value = cm_enrollment_service.CmEnrollment() + client.update_cm_enrollment(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", + "cm_enrollment.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_cm_enrollment_field_headers_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = cm_enrollment_service.UpdateCmEnrollmentRequest() + + request.cm_enrollment.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_cm_enrollment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cm_enrollment_service.CmEnrollment() + ) + await client.update_cm_enrollment(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", + "cm_enrollment.name=name_value", + ) in kw["metadata"] + + +def test_update_cm_enrollment_flattened(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_cm_enrollment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = cm_enrollment_service.CmEnrollment() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_cm_enrollment( + cm_enrollment=cm_enrollment_service.CmEnrollment(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].cm_enrollment + mock_val = cm_enrollment_service.CmEnrollment(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_cm_enrollment_flattened_error(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_cm_enrollment( + cm_enrollment_service.UpdateCmEnrollmentRequest(), + cm_enrollment=cm_enrollment_service.CmEnrollment(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_cm_enrollment_flattened_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_cm_enrollment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = cm_enrollment_service.CmEnrollment() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cm_enrollment_service.CmEnrollment() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_cm_enrollment( + cm_enrollment=cm_enrollment_service.CmEnrollment(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].cm_enrollment + mock_val = cm_enrollment_service.CmEnrollment(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_cm_enrollment_flattened_error_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_cm_enrollment( + cm_enrollment_service.UpdateCmEnrollmentRequest(), + cm_enrollment=cm_enrollment_service.CmEnrollment(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest, + dict, + ], +) +def test_calculate_effective_cm_enrollment(request_type, transport: str = "grpc"): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.calculate_effective_cm_enrollment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + response = client.calculate_effective_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance( + response, cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse + ) + + +def test_calculate_effective_cm_enrollment_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.calculate_effective_cm_enrollment), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.calculate_effective_cm_enrollment(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest( + name="name_value", + ) + + +def test_calculate_effective_cm_enrollment_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.calculate_effective_cm_enrollment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.calculate_effective_cm_enrollment + ] = mock_rpc + request = {} + client.calculate_effective_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.calculate_effective_cm_enrollment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_calculate_effective_cm_enrollment_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.calculate_effective_cm_enrollment + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.calculate_effective_cm_enrollment + ] = mock_rpc + + request = {} + await client.calculate_effective_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.calculate_effective_cm_enrollment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_calculate_effective_cm_enrollment_async( + transport: str = "grpc_asyncio", + request_type=cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest, +): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + 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.calculate_effective_cm_enrollment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + response = await client.calculate_effective_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance( + response, cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse + ) + + +@pytest.mark.asyncio +async def test_calculate_effective_cm_enrollment_async_from_dict(): + await test_calculate_effective_cm_enrollment_async(request_type=dict) + + +def test_calculate_effective_cm_enrollment_field_headers(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.calculate_effective_cm_enrollment), "__call__" + ) as call: + call.return_value = ( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + client.calculate_effective_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_calculate_effective_cm_enrollment_field_headers_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.calculate_effective_cm_enrollment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + await client.calculate_effective_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_calculate_effective_cm_enrollment_flattened(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.calculate_effective_cm_enrollment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.calculate_effective_cm_enrollment( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_calculate_effective_cm_enrollment_flattened_error(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.calculate_effective_cm_enrollment( + cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_calculate_effective_cm_enrollment_flattened_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.calculate_effective_cm_enrollment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.calculate_effective_cm_enrollment( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_calculate_effective_cm_enrollment_flattened_error_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.calculate_effective_cm_enrollment( + cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest(), + name="name_value", + ) + + +def test_update_cm_enrollment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.update_cm_enrollment in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_cm_enrollment + ] = mock_rpc + + request = {} + client.update_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_cm_enrollment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_cm_enrollment_rest_required_fields( + request_type=cm_enrollment_service.UpdateCmEnrollmentRequest, +): + transport_class = transports.CmEnrollmentServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_cm_enrollment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_cm_enrollment._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = cm_enrollment_service.CmEnrollment() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cm_enrollment_service.CmEnrollment.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_cm_enrollment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_cm_enrollment_rest_unset_required_fields(): + transport = transports.CmEnrollmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_cm_enrollment._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("cmEnrollment",))) + + +def test_update_cm_enrollment_rest_flattened(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cm_enrollment_service.CmEnrollment() + + # get arguments that satisfy an http rule for this method + sample_request = { + "cm_enrollment": { + "name": "organizations/sample1/locations/sample2/cmEnrollment" + } + } + + # get truthy value for each flattened field + mock_args = dict( + cm_enrollment=cm_enrollment_service.CmEnrollment(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = cm_enrollment_service.CmEnrollment.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_cm_enrollment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{cm_enrollment.name=organizations/*/locations/*/cmEnrollment}" + % client.transport._host, + args[1], + ) + + +def test_update_cm_enrollment_rest_flattened_error(transport: str = "rest"): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_cm_enrollment( + cm_enrollment_service.UpdateCmEnrollmentRequest(), + cm_enrollment=cm_enrollment_service.CmEnrollment(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_calculate_effective_cm_enrollment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.calculate_effective_cm_enrollment + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.calculate_effective_cm_enrollment + ] = mock_rpc + + request = {} + client.calculate_effective_cm_enrollment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.calculate_effective_cm_enrollment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_calculate_effective_cm_enrollment_rest_required_fields( + request_type=cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest, +): + transport_class = transports.CmEnrollmentServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).calculate_effective_cm_enrollment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).calculate_effective_cm_enrollment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.calculate_effective_cm_enrollment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_calculate_effective_cm_enrollment_rest_unset_required_fields(): + transport = transports.CmEnrollmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.calculate_effective_cm_enrollment._get_unset_required_fields({}) + ) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_calculate_effective_cm_enrollment_rest_flattened(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "organizations/sample1/locations/sample2/cmEnrollment" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.calculate_effective_cm_enrollment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=organizations/*/locations/*/cmEnrollment}:calculate" + % client.transport._host, + args[1], + ) + + +def test_calculate_effective_cm_enrollment_rest_flattened_error( + transport: str = "rest", +): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.calculate_effective_cm_enrollment( + cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CmEnrollmentServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CmEnrollmentServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CmEnrollmentServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CmEnrollmentServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CmEnrollmentServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CmEnrollmentServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CmEnrollmentServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CmEnrollmentServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CmEnrollmentServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CmEnrollmentServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.CmEnrollmentServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.CmEnrollmentServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CmEnrollmentServiceGrpcTransport, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + transports.CmEnrollmentServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = CmEnrollmentServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_cm_enrollment_empty_call_grpc(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_cm_enrollment), "__call__" + ) as call: + call.return_value = cm_enrollment_service.CmEnrollment() + client.update_cm_enrollment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = cm_enrollment_service.UpdateCmEnrollmentRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_calculate_effective_cm_enrollment_empty_call_grpc(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.calculate_effective_cm_enrollment), "__call__" + ) as call: + call.return_value = ( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + client.calculate_effective_cm_enrollment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = CmEnrollmentServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_cm_enrollment_empty_call_grpc_asyncio(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_cm_enrollment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cm_enrollment_service.CmEnrollment( + name="name_value", + enrolled=True, + ) + ) + await client.update_cm_enrollment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = cm_enrollment_service.UpdateCmEnrollmentRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_calculate_effective_cm_enrollment_empty_call_grpc_asyncio(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.calculate_effective_cm_enrollment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + await client.calculate_effective_cm_enrollment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = CmEnrollmentServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_update_cm_enrollment_rest_bad_request( + request_type=cm_enrollment_service.UpdateCmEnrollmentRequest, +): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "cm_enrollment": { + "name": "organizations/sample1/locations/sample2/cmEnrollment" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_cm_enrollment(request) + + +@pytest.mark.parametrize( + "request_type", + [ + cm_enrollment_service.UpdateCmEnrollmentRequest, + dict, + ], +) +def test_update_cm_enrollment_rest_call_success(request_type): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "cm_enrollment": { + "name": "organizations/sample1/locations/sample2/cmEnrollment" + } + } + request_init["cm_enrollment"] = { + "name": "organizations/sample1/locations/sample2/cmEnrollment", + "enrolled": True, + "audit_config": {"destinations": [{"gcs_bucket": "gcs_bucket_value"}]}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = cm_enrollment_service.UpdateCmEnrollmentRequest.meta.fields[ + "cm_enrollment" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["cm_enrollment"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["cm_enrollment"][field])): + del request_init["cm_enrollment"][field][i][subfield] + else: + del request_init["cm_enrollment"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cm_enrollment_service.CmEnrollment( + name="name_value", + enrolled=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cm_enrollment_service.CmEnrollment.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_cm_enrollment(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, cm_enrollment_service.CmEnrollment) + assert response.name == "name_value" + assert response.enrolled is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_cm_enrollment_rest_interceptors(null_interceptor): + transport = transports.CmEnrollmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CmEnrollmentServiceRestInterceptor(), + ) + client = CmEnrollmentServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CmEnrollmentServiceRestInterceptor, "post_update_cm_enrollment" + ) as post, mock.patch.object( + transports.CmEnrollmentServiceRestInterceptor, + "post_update_cm_enrollment_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CmEnrollmentServiceRestInterceptor, "pre_update_cm_enrollment" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = cm_enrollment_service.UpdateCmEnrollmentRequest.pb( + cm_enrollment_service.UpdateCmEnrollmentRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = cm_enrollment_service.CmEnrollment.to_json( + cm_enrollment_service.CmEnrollment() + ) + req.return_value.content = return_value + + request = cm_enrollment_service.UpdateCmEnrollmentRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = cm_enrollment_service.CmEnrollment() + post_with_metadata.return_value = cm_enrollment_service.CmEnrollment(), metadata + + client.update_cm_enrollment( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_calculate_effective_cm_enrollment_rest_bad_request( + request_type=cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest, +): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/locations/sample2/cmEnrollment"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.calculate_effective_cm_enrollment(request) + + +@pytest.mark.parametrize( + "request_type", + [ + cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest, + dict, + ], +) +def test_calculate_effective_cm_enrollment_rest_call_success(request_type): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "organizations/sample1/locations/sample2/cmEnrollment"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.calculate_effective_cm_enrollment(request) + + # Establish that the response is the type that we expect. + assert isinstance( + response, cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_calculate_effective_cm_enrollment_rest_interceptors(null_interceptor): + transport = transports.CmEnrollmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CmEnrollmentServiceRestInterceptor(), + ) + client = CmEnrollmentServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CmEnrollmentServiceRestInterceptor, + "post_calculate_effective_cm_enrollment", + ) as post, mock.patch.object( + transports.CmEnrollmentServiceRestInterceptor, + "post_calculate_effective_cm_enrollment_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CmEnrollmentServiceRestInterceptor, + "pre_calculate_effective_cm_enrollment", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest.pb( + cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = ( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse.to_json( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + ) + req.return_value.content = return_value + + request = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = ( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse() + ) + post_with_metadata.return_value = ( + cm_enrollment_service.CalculateEffectiveCmEnrollmentResponse(), + metadata, + ) + + client.calculate_effective_cm_enrollment( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_location(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.GetLocationRequest, + dict, + ], +) +def test_get_location_rest(request_type): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = locations_pb2.Location() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_location(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_list_locations_rest_bad_request( + request_type=locations_pb2.ListLocationsRequest, +): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict({"name": "organizations/sample1"}, request) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_locations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.ListLocationsRequest, + dict, + ], +) +def test_list_locations_rest(request_type): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "organizations/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = locations_pb2.ListLocationsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_locations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_cancel_operation_rest_bad_request( + request_type=operations_pb2.CancelOperationRequest, +): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.cancel_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.CancelOperationRequest, + dict, + ], +) +def test_cancel_operation_rest(request_type): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = { + "name": "organizations/sample1/locations/sample2/operations/sample3" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "{}" + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.cancel_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_rest_bad_request( + request_type=operations_pb2.DeleteOperationRequest, +): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.DeleteOperationRequest, + dict, + ], +) +def test_delete_operation_rest(request_type): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = { + "name": "organizations/sample1/locations/sample2/operations/sample3" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "{}" + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/locations/sample2/operations/sample3"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = { + "name": "organizations/sample1/locations/sample2/operations/sample3" + } + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + request_type=operations_pb2.ListOperationsRequest, +): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "organizations/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "organizations/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_initialize_client_w_rest(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_cm_enrollment_empty_call_rest(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_cm_enrollment), "__call__" + ) as call: + client.update_cm_enrollment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = cm_enrollment_service.UpdateCmEnrollmentRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_calculate_effective_cm_enrollment_empty_call_rest(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.calculate_effective_cm_enrollment), "__call__" + ) as call: + client.calculate_effective_cm_enrollment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = cm_enrollment_service.CalculateEffectiveCmEnrollmentRequest() + + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.CmEnrollmentServiceGrpcTransport, + ) + + +def test_cm_enrollment_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CmEnrollmentServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_cm_enrollment_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.cloudsecuritycompliance_v1.services.cm_enrollment_service.transports.CmEnrollmentServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.CmEnrollmentServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "update_cm_enrollment", + "calculate_effective_cm_enrollment", + "get_location", + "list_locations", + "get_operation", + "cancel_operation", + "delete_operation", + "list_operations", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_cm_enrollment_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.cloudsecuritycompliance_v1.services.cm_enrollment_service.transports.CmEnrollmentServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CmEnrollmentServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_cm_enrollment_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.cloud.cloudsecuritycompliance_v1.services.cm_enrollment_service.transports.CmEnrollmentServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CmEnrollmentServiceTransport() + adc.assert_called_once() + + +def test_cm_enrollment_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + CmEnrollmentServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CmEnrollmentServiceGrpcTransport, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + ], +) +def test_cm_enrollment_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CmEnrollmentServiceGrpcTransport, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + transports.CmEnrollmentServiceRestTransport, + ], +) +def test_cm_enrollment_service_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.CmEnrollmentServiceGrpcTransport, grpc_helpers), + (transports.CmEnrollmentServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_cm_enrollment_service_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "cloudsecuritycompliance.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="cloudsecuritycompliance.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CmEnrollmentServiceGrpcTransport, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + ], +) +def test_cm_enrollment_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + +def test_cm_enrollment_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.CmEnrollmentServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_cm_enrollment_service_host_no_port(transport_name): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="cloudsecuritycompliance.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "cloudsecuritycompliance.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://cloudsecuritycompliance.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_cm_enrollment_service_host_with_port(transport_name): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="cloudsecuritycompliance.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "cloudsecuritycompliance.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://cloudsecuritycompliance.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_cm_enrollment_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = CmEnrollmentServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = CmEnrollmentServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.update_cm_enrollment._session + session2 = client2.transport.update_cm_enrollment._session + assert session1 != session2 + session1 = client1.transport.calculate_effective_cm_enrollment._session + session2 = client2.transport.calculate_effective_cm_enrollment._session + assert session1 != session2 + + +def test_cm_enrollment_service_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CmEnrollmentServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_cm_enrollment_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CmEnrollmentServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [ + transports.CmEnrollmentServiceGrpcTransport, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + ], +) +def test_cm_enrollment_service_transport_channel_mtls_with_client_cert_source( + transport_class, +): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [ + transports.CmEnrollmentServiceGrpcTransport, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + ], +) +def test_cm_enrollment_service_transport_channel_mtls_with_adc(transport_class): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_cm_enrollment_path(): + organization = "squid" + location = "clam" + expected = "organizations/{organization}/locations/{location}/cmEnrollment".format( + organization=organization, + location=location, + ) + actual = CmEnrollmentServiceClient.cm_enrollment_path(organization, location) + assert expected == actual + + +def test_parse_cm_enrollment_path(): + expected = { + "organization": "whelk", + "location": "octopus", + } + path = CmEnrollmentServiceClient.cm_enrollment_path(**expected) + + # Check that the path construction is reversible. + actual = CmEnrollmentServiceClient.parse_cm_enrollment_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "oyster" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = CmEnrollmentServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = CmEnrollmentServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CmEnrollmentServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "cuttlefish" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = CmEnrollmentServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = CmEnrollmentServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CmEnrollmentServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "winkle" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = CmEnrollmentServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = CmEnrollmentServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CmEnrollmentServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "scallop" + expected = "projects/{project}".format( + project=project, + ) + actual = CmEnrollmentServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = CmEnrollmentServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CmEnrollmentServiceClient.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 = CmEnrollmentServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = CmEnrollmentServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CmEnrollmentServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.CmEnrollmentServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.CmEnrollmentServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = CmEnrollmentServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_delete_operation(transport: str = "grpc"): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_operation_async(transport: str = "grpc_asyncio"): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.DeleteOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_operation_field_headers(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = None + + client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_operation_field_headers_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.DeleteOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_delete_operation_from_dict(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_delete_operation_from_dict_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_cancel_operation(transport: str = "grpc"): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_cancel_operation_async(transport: str = "grpc_asyncio"): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_cancel_operation_field_headers(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = None + + client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_cancel_operation_field_headers_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_cancel_operation_from_dict(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_cancel_operation_from_dict_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_operation(transport: str = "grpc"): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc_asyncio"): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc_asyncio"): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_locations(transport: str = "grpc"): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + response = client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +@pytest.mark.asyncio +async def test_list_locations_async(transport: str = "grpc_asyncio"): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_list_locations_field_headers(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = locations_pb2.ListLocationsResponse() + + client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_locations_field_headers_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + await client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_locations_from_dict(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + + response = client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_locations_from_dict_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_location(transport: str = "grpc"): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + response = client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +@pytest.mark.asyncio +async def test_get_location_async(transport: str = "grpc_asyncio"): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_get_location_field_headers(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials() + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = locations_pb2.Location() + + client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations/abc", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_location_field_headers_async(): + client = CmEnrollmentServiceAsyncClient(credentials=async_anonymous_credentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + await client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations/abc", + ) in kw["metadata"] + + +def test_get_location_from_dict(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + + response = client.get_location( + request={ + "name": "locations/abc", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_location_from_dict_async(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close_grpc(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = CmEnrollmentServiceAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = CmEnrollmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (CmEnrollmentServiceClient, transports.CmEnrollmentServiceGrpcTransport), + ( + CmEnrollmentServiceAsyncClient, + transports.CmEnrollmentServiceGrpcAsyncIOTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-cloud-cloudsecuritycompliance/tests/unit/gapic/cloudsecuritycompliance_v1/test_config.py b/packages/google-cloud-cloudsecuritycompliance/tests/unit/gapic/cloudsecuritycompliance_v1/test_config.py index a3fdc2617d1c..84e804921c07 100644 --- a/packages/google-cloud-cloudsecuritycompliance/tests/unit/gapic/cloudsecuritycompliance_v1/test_config.py +++ b/packages/google-cloud-cloudsecuritycompliance/tests/unit/gapic/cloudsecuritycompliance_v1/test_config.py @@ -6406,6 +6406,8 @@ def test_get_cloud_control_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() ).get_cloud_control._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("major_revision_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -6460,7 +6462,7 @@ def test_get_cloud_control_rest_unset_required_fields(): ) unset_fields = transport.get_cloud_control._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + assert set(unset_fields) == (set(("majorRevisionId",)) & set(("name",))) def test_get_cloud_control_rest_flattened():