diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d27edd..9a0b9ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [1.1.0](https://www.github.com/googleapis/python-binary-authorization/compare/v1.0.1...v1.1.0) (2021-11-09) + + +### Features + +* **v1beta1:** add new admission rule types to Policy ([#95](https://www.github.com/googleapis/python-binary-authorization/issues/95)) ([f25d17a](https://www.github.com/googleapis/python-binary-authorization/commit/f25d17abaefe4a2d317161ec15b867b33eb3e8ba)) +* **v1beta1:** add SystemPolicyV1Beta1 service ([f25d17a](https://www.github.com/googleapis/python-binary-authorization/commit/f25d17abaefe4a2d317161ec15b867b33eb3e8ba)) +* **v1beta1:** update SignatureAlgorithm enum to match algorithm names in KMS ([f25d17a](https://www.github.com/googleapis/python-binary-authorization/commit/f25d17abaefe4a2d317161ec15b867b33eb3e8ba)) + ### [1.0.1](https://www.github.com/googleapis/python-binary-authorization/compare/v1.0.0...v1.0.1) (2021-11-01) diff --git a/docs/binaryauthorization_v1beta1/services.rst b/docs/binaryauthorization_v1beta1/services.rst index e96610a..0d0e455 100644 --- a/docs/binaryauthorization_v1beta1/services.rst +++ b/docs/binaryauthorization_v1beta1/services.rst @@ -4,3 +4,4 @@ Services for Google Cloud Binaryauthorization v1beta1 API :maxdepth: 2 binauthz_management_service_v1_beta1 + system_policy_v1_beta1 diff --git a/docs/binaryauthorization_v1beta1/system_policy_v1_beta1.rst b/docs/binaryauthorization_v1beta1/system_policy_v1_beta1.rst new file mode 100644 index 0000000..70a68bc --- /dev/null +++ b/docs/binaryauthorization_v1beta1/system_policy_v1_beta1.rst @@ -0,0 +1,6 @@ +SystemPolicyV1Beta1 +------------------------------------- + +.. automodule:: google.cloud.binaryauthorization_v1beta1.services.system_policy_v1_beta1 + :members: + :inherited-members: diff --git a/google/cloud/binaryauthorization_v1beta1/__init__.py b/google/cloud/binaryauthorization_v1beta1/__init__.py index 200eb17..40c2c2b 100644 --- a/google/cloud/binaryauthorization_v1beta1/__init__.py +++ b/google/cloud/binaryauthorization_v1beta1/__init__.py @@ -20,6 +20,8 @@ from .services.binauthz_management_service_v1_beta1 import ( BinauthzManagementServiceV1Beta1AsyncClient, ) +from .services.system_policy_v1_beta1 import SystemPolicyV1Beta1Client +from .services.system_policy_v1_beta1 import SystemPolicyV1Beta1AsyncClient from .types.continuous_validation_logging import ContinuousValidationEvent from .types.resources import AdmissionRule @@ -33,6 +35,7 @@ from .types.service import DeleteAttestorRequest from .types.service import GetAttestorRequest from .types.service import GetPolicyRequest +from .types.service import GetSystemPolicyRequest from .types.service import ListAttestorsRequest from .types.service import ListAttestorsResponse from .types.service import UpdateAttestorRequest @@ -40,6 +43,7 @@ __all__ = ( "BinauthzManagementServiceV1Beta1AsyncClient", + "SystemPolicyV1Beta1AsyncClient", "AdmissionRule", "AdmissionWhitelistPattern", "Attestor", @@ -50,10 +54,12 @@ "DeleteAttestorRequest", "GetAttestorRequest", "GetPolicyRequest", + "GetSystemPolicyRequest", "ListAttestorsRequest", "ListAttestorsResponse", "PkixPublicKey", "Policy", + "SystemPolicyV1Beta1Client", "UpdateAttestorRequest", "UpdatePolicyRequest", "UserOwnedDrydockNote", diff --git a/google/cloud/binaryauthorization_v1beta1/gapic_metadata.json b/google/cloud/binaryauthorization_v1beta1/gapic_metadata.json index 8e56955..65f5f50 100644 --- a/google/cloud/binaryauthorization_v1beta1/gapic_metadata.json +++ b/google/cloud/binaryauthorization_v1beta1/gapic_metadata.json @@ -88,6 +88,30 @@ } } } + }, + "SystemPolicyV1Beta1": { + "clients": { + "grpc": { + "libraryClient": "SystemPolicyV1Beta1Client", + "rpcs": { + "GetSystemPolicy": { + "methods": [ + "get_system_policy" + ] + } + } + }, + "grpc-async": { + "libraryClient": "SystemPolicyV1Beta1AsyncClient", + "rpcs": { + "GetSystemPolicy": { + "methods": [ + "get_system_policy" + ] + } + } + } + } } } } diff --git a/google/cloud/binaryauthorization_v1beta1/services/binauthz_management_service_v1_beta1/async_client.py b/google/cloud/binaryauthorization_v1beta1/services/binauthz_management_service_v1_beta1/async_client.py index b606e21..e77da1a 100644 --- a/google/cloud/binaryauthorization_v1beta1/services/binauthz_management_service_v1_beta1/async_client.py +++ b/google/cloud/binaryauthorization_v1beta1/services/binauthz_management_service_v1_beta1/async_client.py @@ -237,8 +237,9 @@ async def get_policy( Returns: google.cloud.binaryauthorization_v1beta1.types.Policy: - A [policy][google.cloud.binaryauthorization.v1beta1.Policy] for container - image binary authorization. + A + [policy][google.cloud.binaryauthorization.v1beta1.Policy] + for Binary Authorization. """ # Create or coerce a protobuf request object. @@ -329,8 +330,9 @@ async def update_policy( Returns: google.cloud.binaryauthorization_v1beta1.types.Policy: - A [policy][google.cloud.binaryauthorization.v1beta1.Policy] for container - image binary authorization. + A + [policy][google.cloud.binaryauthorization.v1beta1.Policy] + for Binary Authorization. """ # Create or coerce a protobuf request object. @@ -441,9 +443,9 @@ async def create_attestor( Returns: google.cloud.binaryauthorization_v1beta1.types.Attestor: - An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests - to container image artifacts. An existing attestor - cannot be modified except where indicated. + An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests to container image + artifacts. An existing attestor cannot be modified + except where indicated. """ # Create or coerce a protobuf request object. @@ -522,9 +524,9 @@ async def get_attestor( Returns: google.cloud.binaryauthorization_v1beta1.types.Attestor: - An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests - to container image artifacts. An existing attestor - cannot be modified except where indicated. + An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests to container image + artifacts. An existing attestor cannot be modified + except where indicated. """ # Create or coerce a protobuf request object. @@ -612,9 +614,9 @@ async def update_attestor( Returns: google.cloud.binaryauthorization_v1beta1.types.Attestor: - An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests - to container image artifacts. An existing attestor - cannot be modified except where indicated. + An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests to container image + artifacts. An existing attestor cannot be modified + except where indicated. """ # Create or coerce a protobuf request object. diff --git a/google/cloud/binaryauthorization_v1beta1/services/binauthz_management_service_v1_beta1/client.py b/google/cloud/binaryauthorization_v1beta1/services/binauthz_management_service_v1_beta1/client.py index 4e62d5f..bb7fd4e 100644 --- a/google/cloud/binaryauthorization_v1beta1/services/binauthz_management_service_v1_beta1/client.py +++ b/google/cloud/binaryauthorization_v1beta1/services/binauthz_management_service_v1_beta1/client.py @@ -422,8 +422,9 @@ def get_policy( Returns: google.cloud.binaryauthorization_v1beta1.types.Policy: - A [policy][google.cloud.binaryauthorization.v1beta1.Policy] for container - image binary authorization. + A + [policy][google.cloud.binaryauthorization.v1beta1.Policy] + for Binary Authorization. """ # Create or coerce a protobuf request object. @@ -504,8 +505,9 @@ def update_policy( Returns: google.cloud.binaryauthorization_v1beta1.types.Policy: - A [policy][google.cloud.binaryauthorization.v1beta1.Policy] for container - image binary authorization. + A + [policy][google.cloud.binaryauthorization.v1beta1.Policy] + for Binary Authorization. """ # Create or coerce a protobuf request object. @@ -606,9 +608,9 @@ def create_attestor( Returns: google.cloud.binaryauthorization_v1beta1.types.Attestor: - An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests - to container image artifacts. An existing attestor - cannot be modified except where indicated. + An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests to container image + artifacts. An existing attestor cannot be modified + except where indicated. """ # Create or coerce a protobuf request object. @@ -687,9 +689,9 @@ def get_attestor( Returns: google.cloud.binaryauthorization_v1beta1.types.Attestor: - An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests - to container image artifacts. An existing attestor - cannot be modified except where indicated. + An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests to container image + artifacts. An existing attestor cannot be modified + except where indicated. """ # Create or coerce a protobuf request object. @@ -767,9 +769,9 @@ def update_attestor( Returns: google.cloud.binaryauthorization_v1beta1.types.Attestor: - An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests - to container image artifacts. An existing attestor - cannot be modified except where indicated. + An [attestor][google.cloud.binaryauthorization.v1beta1.Attestor] that attests to container image + artifacts. An existing attestor cannot be modified + except where indicated. """ # Create or coerce a protobuf request object. diff --git a/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/__init__.py b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/__init__.py new file mode 100644 index 0000000..f56960f --- /dev/null +++ b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import SystemPolicyV1Beta1Client +from .async_client import SystemPolicyV1Beta1AsyncClient + +__all__ = ( + "SystemPolicyV1Beta1Client", + "SystemPolicyV1Beta1AsyncClient", +) diff --git a/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/async_client.py b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/async_client.py new file mode 100644 index 0000000..cd33b74 --- /dev/null +++ b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/async_client.py @@ -0,0 +1,259 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import functools +import re +from typing import Dict, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core.client_options import ClientOptions # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +OptionalRetry = Union[retries.Retry, object] + +from google.cloud.binaryauthorization_v1beta1.types import resources +from google.cloud.binaryauthorization_v1beta1.types import service +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import SystemPolicyV1Beta1Transport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import SystemPolicyV1Beta1GrpcAsyncIOTransport +from .client import SystemPolicyV1Beta1Client + + +class SystemPolicyV1Beta1AsyncClient: + """API for working with the system policy.""" + + _client: SystemPolicyV1Beta1Client + + DEFAULT_ENDPOINT = SystemPolicyV1Beta1Client.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = SystemPolicyV1Beta1Client.DEFAULT_MTLS_ENDPOINT + + policy_path = staticmethod(SystemPolicyV1Beta1Client.policy_path) + parse_policy_path = staticmethod(SystemPolicyV1Beta1Client.parse_policy_path) + common_billing_account_path = staticmethod( + SystemPolicyV1Beta1Client.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + SystemPolicyV1Beta1Client.parse_common_billing_account_path + ) + common_folder_path = staticmethod(SystemPolicyV1Beta1Client.common_folder_path) + parse_common_folder_path = staticmethod( + SystemPolicyV1Beta1Client.parse_common_folder_path + ) + common_organization_path = staticmethod( + SystemPolicyV1Beta1Client.common_organization_path + ) + parse_common_organization_path = staticmethod( + SystemPolicyV1Beta1Client.parse_common_organization_path + ) + common_project_path = staticmethod(SystemPolicyV1Beta1Client.common_project_path) + parse_common_project_path = staticmethod( + SystemPolicyV1Beta1Client.parse_common_project_path + ) + common_location_path = staticmethod(SystemPolicyV1Beta1Client.common_location_path) + parse_common_location_path = staticmethod( + SystemPolicyV1Beta1Client.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: + SystemPolicyV1Beta1AsyncClient: The constructed client. + """ + return SystemPolicyV1Beta1Client.from_service_account_info.__func__(SystemPolicyV1Beta1AsyncClient, 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: + SystemPolicyV1Beta1AsyncClient: The constructed client. + """ + return SystemPolicyV1Beta1Client.from_service_account_file.__func__(SystemPolicyV1Beta1AsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SystemPolicyV1Beta1Transport: + """Returns the transport used by the client instance. + + Returns: + SystemPolicyV1Beta1Transport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial( + type(SystemPolicyV1Beta1Client).get_transport_class, + type(SystemPolicyV1Beta1Client), + ) + + def __init__( + self, + *, + credentials: ga_credentials.Credentials = None, + transport: Union[str, SystemPolicyV1Beta1Transport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the system policy v1 beta1 client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.SystemPolicyV1Beta1Transport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "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). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS 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. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = SystemPolicyV1Beta1Client( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def get_system_policy( + self, + request: Union[service.GetSystemPolicyRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resources.Policy: + r"""Gets the current system policy in the specified + location. + + Args: + request (Union[google.cloud.binaryauthorization_v1beta1.types.GetSystemPolicyRequest, dict]): + The request object. Request to read the current system + policy. + name (:class:`str`): + Required. The resource name, in the format + ``locations/*/policy``. Note that the system policy is + not associated with a project. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.binaryauthorization_v1beta1.types.Policy: + A + [policy][google.cloud.binaryauthorization.v1beta1.Policy] + for Binary Authorization. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = service.GetSystemPolicyRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_system_policy, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-binary-authorization", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("SystemPolicyV1Beta1AsyncClient",) diff --git a/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/client.py b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/client.py new file mode 100644 index 0000000..2e1ac8d --- /dev/null +++ b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/client.py @@ -0,0 +1,448 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from distutils import util +import os +import re +from typing import Dict, Optional, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +OptionalRetry = Union[retries.Retry, object] + +from google.cloud.binaryauthorization_v1beta1.types import resources +from google.cloud.binaryauthorization_v1beta1.types import service +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import SystemPolicyV1Beta1Transport, DEFAULT_CLIENT_INFO +from .transports.grpc import SystemPolicyV1Beta1GrpcTransport +from .transports.grpc_asyncio import SystemPolicyV1Beta1GrpcAsyncIOTransport + + +class SystemPolicyV1Beta1ClientMeta(type): + """Metaclass for the SystemPolicyV1Beta1 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[SystemPolicyV1Beta1Transport]] + _transport_registry["grpc"] = SystemPolicyV1Beta1GrpcTransport + _transport_registry["grpc_asyncio"] = SystemPolicyV1Beta1GrpcAsyncIOTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[SystemPolicyV1Beta1Transport]: + """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 SystemPolicyV1Beta1Client(metaclass=SystemPolicyV1Beta1ClientMeta): + """API for working with the system policy.""" + + @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") + + DEFAULT_ENDPOINT = "binaryauthorization.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SystemPolicyV1Beta1Client: 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: + SystemPolicyV1Beta1Client: 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) -> SystemPolicyV1Beta1Transport: + """Returns the transport used by the client instance. + + Returns: + SystemPolicyV1Beta1Transport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def policy_path(project: str,) -> str: + """Returns a fully-qualified policy string.""" + return "projects/{project}/policy".format(project=project,) + + @staticmethod + def parse_policy_path(path: str) -> Dict[str, str]: + """Parses a policy path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/policy$", 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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, SystemPolicyV1Beta1Transport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the system policy v1 beta1 client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, SystemPolicyV1Beta1Transport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "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). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS 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. + 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. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + use_client_cert = bool( + util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, SystemPolicyV1Beta1Transport): + # transport is a SystemPolicyV1Beta1Transport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def get_system_policy( + self, + request: Union[service.GetSystemPolicyRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> resources.Policy: + r"""Gets the current system policy in the specified + location. + + Args: + request (Union[google.cloud.binaryauthorization_v1beta1.types.GetSystemPolicyRequest, dict]): + The request object. Request to read the current system + policy. + name (str): + Required. The resource name, in the format + ``locations/*/policy``. Note that the system policy is + not associated with a project. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.binaryauthorization_v1beta1.types.Policy: + A + [policy][google.cloud.binaryauthorization.v1beta1.Policy] + for Binary Authorization. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a service.GetSystemPolicyRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, service.GetSystemPolicyRequest): + request = service.GetSystemPolicyRequest(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_system_policy] + + # 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),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def __enter__(self): + 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() + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-binary-authorization", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("SystemPolicyV1Beta1Client",) diff --git a/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/__init__.py b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/__init__.py new file mode 100644 index 0000000..75e13a4 --- /dev/null +++ b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import SystemPolicyV1Beta1Transport +from .grpc import SystemPolicyV1Beta1GrpcTransport +from .grpc_asyncio import SystemPolicyV1Beta1GrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[SystemPolicyV1Beta1Transport]] +_transport_registry["grpc"] = SystemPolicyV1Beta1GrpcTransport +_transport_registry["grpc_asyncio"] = SystemPolicyV1Beta1GrpcAsyncIOTransport + +__all__ = ( + "SystemPolicyV1Beta1Transport", + "SystemPolicyV1Beta1GrpcTransport", + "SystemPolicyV1Beta1GrpcAsyncIOTransport", +) diff --git a/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/base.py b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/base.py new file mode 100644 index 0000000..e5cb239 --- /dev/null +++ b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/base.py @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.binaryauthorization_v1beta1.types import resources +from google.cloud.binaryauthorization_v1beta1.types import service + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-binary-authorization", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class SystemPolicyV1Beta1Transport(abc.ABC): + """Abstract transport class for SystemPolicyV1Beta1.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + DEFAULT_HOST: str = "binaryauthorization.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: 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, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + ) + + elif credentials is None: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # 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 + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.get_system_policy: gapic_v1.method.wrap_method( + self.get_system_policy, 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 get_system_policy( + self, + ) -> Callable[ + [service.GetSystemPolicyRequest], + Union[resources.Policy, Awaitable[resources.Policy]], + ]: + raise NotImplementedError() + + +__all__ = ("SystemPolicyV1Beta1Transport",) diff --git a/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/grpc.py b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/grpc.py new file mode 100644 index 0000000..16c9b41 --- /dev/null +++ b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/grpc.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers # type: ignore +from google.api_core import gapic_v1 # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.binaryauthorization_v1beta1.types import resources +from google.cloud.binaryauthorization_v1beta1.types import service +from .base import SystemPolicyV1Beta1Transport, DEFAULT_CLIENT_INFO + + +class SystemPolicyV1Beta1GrpcTransport(SystemPolicyV1Beta1Transport): + """gRPC backend transport for SystemPolicyV1Beta1. + + API for working with the system policy. + + 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 = "binaryauthorization.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "binaryauthorization.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def get_system_policy( + self, + ) -> Callable[[service.GetSystemPolicyRequest], resources.Policy]: + r"""Return a callable for the get system policy method over gRPC. + + Gets the current system policy in the specified + location. + + Returns: + Callable[[~.GetSystemPolicyRequest], + ~.Policy]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_system_policy" not in self._stubs: + self._stubs["get_system_policy"] = self.grpc_channel.unary_unary( + "/google.cloud.binaryauthorization.v1beta1.SystemPolicyV1Beta1/GetSystemPolicy", + request_serializer=service.GetSystemPolicyRequest.serialize, + response_deserializer=resources.Policy.deserialize, + ) + return self._stubs["get_system_policy"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("SystemPolicyV1Beta1GrpcTransport",) diff --git a/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/grpc_asyncio.py b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/grpc_asyncio.py new file mode 100644 index 0000000..9a6adf0 --- /dev/null +++ b/google/cloud/binaryauthorization_v1beta1/services/system_policy_v1_beta1/transports/grpc_asyncio.py @@ -0,0 +1,262 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers_async # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.binaryauthorization_v1beta1.types import resources +from google.cloud.binaryauthorization_v1beta1.types import service +from .base import SystemPolicyV1Beta1Transport, DEFAULT_CLIENT_INFO +from .grpc import SystemPolicyV1Beta1GrpcTransport + + +class SystemPolicyV1Beta1GrpcAsyncIOTransport(SystemPolicyV1Beta1Transport): + """gRPC AsyncIO backend transport for SystemPolicyV1Beta1. + + API for working with the system policy. + + 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 = "binaryauthorization.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "binaryauthorization.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def get_system_policy( + self, + ) -> Callable[[service.GetSystemPolicyRequest], Awaitable[resources.Policy]]: + r"""Return a callable for the get system policy method over gRPC. + + Gets the current system policy in the specified + location. + + Returns: + Callable[[~.GetSystemPolicyRequest], + Awaitable[~.Policy]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_system_policy" not in self._stubs: + self._stubs["get_system_policy"] = self.grpc_channel.unary_unary( + "/google.cloud.binaryauthorization.v1beta1.SystemPolicyV1Beta1/GetSystemPolicy", + request_serializer=service.GetSystemPolicyRequest.serialize, + response_deserializer=resources.Policy.deserialize, + ) + return self._stubs["get_system_policy"] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ("SystemPolicyV1Beta1GrpcAsyncIOTransport",) diff --git a/google/cloud/binaryauthorization_v1beta1/types/__init__.py b/google/cloud/binaryauthorization_v1beta1/types/__init__.py index 607c905..2ccdf4c 100644 --- a/google/cloud/binaryauthorization_v1beta1/types/__init__.py +++ b/google/cloud/binaryauthorization_v1beta1/types/__init__.py @@ -28,6 +28,7 @@ DeleteAttestorRequest, GetAttestorRequest, GetPolicyRequest, + GetSystemPolicyRequest, ListAttestorsRequest, ListAttestorsResponse, UpdateAttestorRequest, @@ -47,6 +48,7 @@ "DeleteAttestorRequest", "GetAttestorRequest", "GetPolicyRequest", + "GetSystemPolicyRequest", "ListAttestorsRequest", "ListAttestorsResponse", "UpdateAttestorRequest", diff --git a/google/cloud/binaryauthorization_v1beta1/types/resources.py b/google/cloud/binaryauthorization_v1beta1/types/resources.py index 61a6d3a..f615dc7 100644 --- a/google/cloud/binaryauthorization_v1beta1/types/resources.py +++ b/google/cloud/binaryauthorization_v1beta1/types/resources.py @@ -34,7 +34,7 @@ class Policy(proto.Message): r"""A [policy][google.cloud.binaryauthorization.v1beta1.Policy] for - container image binary authorization. + Binary Authorization. Attributes: name (str): @@ -64,6 +64,19 @@ class Policy(proto.Message): zone (e.g. us-central1-a) or a region (e.g. us-central1). For ``clusterId`` syntax restrictions see https://cloud.google.com/container-engine/reference/rest/v1/projects.zones.clusters. + kubernetes_namespace_admission_rules (Sequence[google.cloud.binaryauthorization_v1beta1.types.Policy.KubernetesNamespaceAdmissionRulesEntry]): + Optional. Per-kubernetes-namespace admission rules. K8s + namespace spec format: ``[a-z.-]+``, e.g. ``some-namespace`` + kubernetes_service_account_admission_rules (Sequence[google.cloud.binaryauthorization_v1beta1.types.Policy.KubernetesServiceAccountAdmissionRulesEntry]): + Optional. Per-kubernetes-service-account admission rules. + Service account spec format: ``namespace:serviceaccount``. + e.g. ``test-ns:default`` + istio_service_identity_admission_rules (Sequence[google.cloud.binaryauthorization_v1beta1.types.Policy.IstioServiceIdentityAdmissionRulesEntry]): + Optional. Per-istio-service-identity admission rules. Istio + service identity spec format: + ``spiffe:///ns//sa/`` or + ``/ns//sa/`` e.g. + ``spiffe://example.com/ns/test-ns/sa/default`` default_admission_rule (google.cloud.binaryauthorization_v1beta1.types.AdmissionRule): Required. Default admission rule for a cluster without a per-cluster, per- kubernetes- @@ -91,6 +104,15 @@ class GlobalPolicyEvaluationMode(proto.Enum): cluster_admission_rules = proto.MapField( proto.STRING, proto.MESSAGE, number=3, message="AdmissionRule", ) + kubernetes_namespace_admission_rules = proto.MapField( + proto.STRING, proto.MESSAGE, number=10, message="AdmissionRule", + ) + kubernetes_service_account_admission_rules = proto.MapField( + proto.STRING, proto.MESSAGE, number=8, message="AdmissionRule", + ) + istio_service_identity_admission_rules = proto.MapField( + proto.STRING, proto.MESSAGE, number=9, message="AdmissionRule", + ) default_admission_rule = proto.Field( proto.MESSAGE, number=4, message="AdmissionRule", ) @@ -105,10 +127,14 @@ class AdmissionWhitelistPattern(proto.Message): Attributes: name_pattern (str): - An image name pattern to allow, in the form + An image name pattern to allowlist, in the form ``registry/path/to/image``. This supports a trailing ``*`` as a wildcard, but this is allowed only in text after the - ``registry/`` part. + ``registry/`` part. ``*`` wildcard does not match ``/``, + i.e., ``gcr.io/nginx*`` matches ``gcr.io/nginx@latest``, but + it does not match ``gcr.io/nginx/image``. This also supports + a trailing ``**`` wildcard which matches subdirectories, + i.e., ``gcr.io/nginx**`` matches ``gcr.io/nginx/image``. """ name_pattern = proto.Field(proto.STRING, number=1,) @@ -275,6 +301,7 @@ class SignatureAlgorithm(proto.Enum): the future, BinAuthz might support additional public key types independently of Tink and/or KMS. """ + _pb_options = {"allow_alias": True} SIGNATURE_ALGORITHM_UNSPECIFIED = 0 RSA_PSS_2048_SHA256 = 1 RSA_PSS_3072_SHA256 = 2 @@ -285,8 +312,11 @@ class SignatureAlgorithm(proto.Enum): RSA_SIGN_PKCS1_4096_SHA256 = 7 RSA_SIGN_PKCS1_4096_SHA512 = 8 ECDSA_P256_SHA256 = 9 + EC_SIGN_P256_SHA256 = 9 ECDSA_P384_SHA384 = 10 + EC_SIGN_P384_SHA384 = 10 ECDSA_P521_SHA512 = 11 + EC_SIGN_P521_SHA512 = 11 public_key_pem = proto.Field(proto.STRING, number=1,) signature_algorithm = proto.Field(proto.ENUM, number=2, enum=SignatureAlgorithm,) diff --git a/google/cloud/binaryauthorization_v1beta1/types/service.py b/google/cloud/binaryauthorization_v1beta1/types/service.py index f4bc93d..e415efc 100644 --- a/google/cloud/binaryauthorization_v1beta1/types/service.py +++ b/google/cloud/binaryauthorization_v1beta1/types/service.py @@ -29,6 +29,7 @@ "ListAttestorsRequest", "ListAttestorsResponse", "DeleteAttestorRequest", + "GetSystemPolicyRequest", }, ) @@ -180,4 +181,17 @@ class DeleteAttestorRequest(proto.Message): name = proto.Field(proto.STRING, number=1,) +class GetSystemPolicyRequest(proto.Message): + r"""Request to read the current system policy. + + Attributes: + name (str): + Required. The resource name, in the format + ``locations/*/policy``. Note that the system policy is not + associated with a project. + """ + + name = proto.Field(proto.STRING, number=1,) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/scripts/fixup_binaryauthorization_v1beta1_keywords.py b/scripts/fixup_binaryauthorization_v1beta1_keywords.py index d8d091d..f1147e2 100644 --- a/scripts/fixup_binaryauthorization_v1beta1_keywords.py +++ b/scripts/fixup_binaryauthorization_v1beta1_keywords.py @@ -43,6 +43,7 @@ class binaryauthorizationCallTransformer(cst.CSTTransformer): 'delete_attestor': ('name', ), 'get_attestor': ('name', ), 'get_policy': ('name', ), + 'get_system_policy': ('name', ), 'list_attestors': ('parent', 'page_size', 'page_token', ), 'update_attestor': ('attestor', ), 'update_policy': ('policy', ), diff --git a/setup.py b/setup.py index bea03e6..70e0aff 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ import setuptools # type: ignore -version = "1.0.1" +version = "1.1.0" package_root = os.path.abspath(os.path.dirname(__file__)) diff --git a/tests/unit/gapic/binaryauthorization_v1beta1/test_system_policy_v1_beta1.py b/tests/unit/gapic/binaryauthorization_v1beta1/test_system_policy_v1_beta1.py new file mode 100644 index 0000000..7c75fcc --- /dev/null +++ b/tests/unit/gapic/binaryauthorization_v1beta1/test_system_policy_v1_beta1.py @@ -0,0 +1,1320 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.binaryauthorization_v1beta1.services.system_policy_v1_beta1 import ( + SystemPolicyV1Beta1AsyncClient, +) +from google.cloud.binaryauthorization_v1beta1.services.system_policy_v1_beta1 import ( + SystemPolicyV1Beta1Client, +) +from google.cloud.binaryauthorization_v1beta1.services.system_policy_v1_beta1 import ( + transports, +) +from google.cloud.binaryauthorization_v1beta1.types import resources +from google.cloud.binaryauthorization_v1beta1.types import service +from google.oauth2 import service_account +from google.protobuf import timestamp_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +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 SystemPolicyV1Beta1Client._get_default_mtls_endpoint(None) is None + assert ( + SystemPolicyV1Beta1Client._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + SystemPolicyV1Beta1Client._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + SystemPolicyV1Beta1Client._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + SystemPolicyV1Beta1Client._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + SystemPolicyV1Beta1Client._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +@pytest.mark.parametrize( + "client_class", [SystemPolicyV1Beta1Client, SystemPolicyV1Beta1AsyncClient,] +) +def test_system_policy_v1_beta1_client_from_service_account_info(client_class): + 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) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "binaryauthorization.googleapis.com:443" + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.SystemPolicyV1Beta1GrpcTransport, "grpc"), + (transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, "grpc_asyncio"), + ], +) +def test_system_policy_v1_beta1_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", [SystemPolicyV1Beta1Client, SystemPolicyV1Beta1AsyncClient,] +) +def test_system_policy_v1_beta1_client_from_service_account_file(client_class): + 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") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "binaryauthorization.googleapis.com:443" + + +def test_system_policy_v1_beta1_client_get_transport_class(): + transport = SystemPolicyV1Beta1Client.get_transport_class() + available_transports = [ + transports.SystemPolicyV1Beta1GrpcTransport, + ] + assert transport in available_transports + + transport = SystemPolicyV1Beta1Client.get_transport_class("grpc") + assert transport == transports.SystemPolicyV1Beta1GrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + SystemPolicyV1Beta1Client, + transports.SystemPolicyV1Beta1GrpcTransport, + "grpc", + ), + ( + SystemPolicyV1Beta1AsyncClient, + transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +@mock.patch.object( + SystemPolicyV1Beta1Client, + "DEFAULT_ENDPOINT", + modify_default_endpoint(SystemPolicyV1Beta1Client), +) +@mock.patch.object( + SystemPolicyV1Beta1AsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(SystemPolicyV1Beta1AsyncClient), +) +def test_system_policy_v1_beta1_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(SystemPolicyV1Beta1Client, "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(SystemPolicyV1Beta1Client, "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, + ) + + # 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, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # 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, + ) + + # 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): + client = client_class() + + # 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): + client = client_class() + + # 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(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + SystemPolicyV1Beta1Client, + transports.SystemPolicyV1Beta1GrpcTransport, + "grpc", + "true", + ), + ( + SystemPolicyV1Beta1AsyncClient, + transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + SystemPolicyV1Beta1Client, + transports.SystemPolicyV1Beta1GrpcTransport, + "grpc", + "false", + ), + ( + SystemPolicyV1Beta1AsyncClient, + transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + SystemPolicyV1Beta1Client, + "DEFAULT_ENDPOINT", + modify_default_endpoint(SystemPolicyV1Beta1Client), +) +@mock.patch.object( + SystemPolicyV1Beta1AsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(SystemPolicyV1Beta1AsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_system_policy_v1_beta1_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(transport=transport_name, client_options=options) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + 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, + ) + + # 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 + 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, + ) + + # 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, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + SystemPolicyV1Beta1Client, + transports.SystemPolicyV1Beta1GrpcTransport, + "grpc", + ), + ( + SystemPolicyV1Beta1AsyncClient, + transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_system_policy_v1_beta1_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(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + 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, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + SystemPolicyV1Beta1Client, + transports.SystemPolicyV1Beta1GrpcTransport, + "grpc", + ), + ( + SystemPolicyV1Beta1AsyncClient, + transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_system_policy_v1_beta1_client_client_options_credentials_file( + client_class, transport_class, transport_name +): + # 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(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_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, + ) + + +def test_system_policy_v1_beta1_client_client_options_from_dict(): + with mock.patch( + "google.cloud.binaryauthorization_v1beta1.services.system_policy_v1_beta1.transports.SystemPolicyV1Beta1GrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = SystemPolicyV1Beta1Client( + 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, + ) + + +def test_get_system_policy( + transport: str = "grpc", request_type=service.GetSystemPolicyRequest +): + client = SystemPolicyV1Beta1Client( + 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_system_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resources.Policy( + name="name_value", + description="description_value", + global_policy_evaluation_mode=resources.Policy.GlobalPolicyEvaluationMode.ENABLE, + ) + response = client.get_system_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == service.GetSystemPolicyRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, resources.Policy) + assert response.name == "name_value" + assert response.description == "description_value" + assert ( + response.global_policy_evaluation_mode + == resources.Policy.GlobalPolicyEvaluationMode.ENABLE + ) + + +def test_get_system_policy_from_dict(): + test_get_system_policy(request_type=dict) + + +def test_get_system_policy_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = SystemPolicyV1Beta1Client( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_system_policy), "__call__" + ) as call: + client.get_system_policy() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == service.GetSystemPolicyRequest() + + +@pytest.mark.asyncio +async def test_get_system_policy_async( + transport: str = "grpc_asyncio", request_type=service.GetSystemPolicyRequest +): + client = SystemPolicyV1Beta1AsyncClient( + 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_system_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + resources.Policy( + name="name_value", + description="description_value", + global_policy_evaluation_mode=resources.Policy.GlobalPolicyEvaluationMode.ENABLE, + ) + ) + response = await client.get_system_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == service.GetSystemPolicyRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, resources.Policy) + assert response.name == "name_value" + assert response.description == "description_value" + assert ( + response.global_policy_evaluation_mode + == resources.Policy.GlobalPolicyEvaluationMode.ENABLE + ) + + +@pytest.mark.asyncio +async def test_get_system_policy_async_from_dict(): + await test_get_system_policy_async(request_type=dict) + + +def test_get_system_policy_field_headers(): + client = SystemPolicyV1Beta1Client( + 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 = service.GetSystemPolicyRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_system_policy), "__call__" + ) as call: + call.return_value = resources.Policy() + client.get_system_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_system_policy_field_headers_async(): + client = SystemPolicyV1Beta1AsyncClient( + 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 = service.GetSystemPolicyRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_system_policy), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(resources.Policy()) + await client.get_system_policy(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] + + +def test_get_system_policy_flattened(): + client = SystemPolicyV1Beta1Client( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_system_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resources.Policy() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_system_policy(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] + assert args[0].name == "name_value" + + +def test_get_system_policy_flattened_error(): + client = SystemPolicyV1Beta1Client( + 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_system_policy( + service.GetSystemPolicyRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_system_policy_flattened_async(): + client = SystemPolicyV1Beta1AsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_system_policy), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = resources.Policy() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(resources.Policy()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_system_policy(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] + assert args[0].name == "name_value" + + +@pytest.mark.asyncio +async def test_get_system_policy_flattened_error_async(): + client = SystemPolicyV1Beta1AsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_system_policy( + service.GetSystemPolicyRequest(), name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.SystemPolicyV1Beta1GrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SystemPolicyV1Beta1Client( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.SystemPolicyV1Beta1GrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SystemPolicyV1Beta1Client( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.SystemPolicyV1Beta1GrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SystemPolicyV1Beta1Client( + client_options={"scopes": ["1", "2"]}, transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.SystemPolicyV1Beta1GrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = SystemPolicyV1Beta1Client(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.SystemPolicyV1Beta1GrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.SystemPolicyV1Beta1GrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SystemPolicyV1Beta1GrpcTransport, + transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, + ], +) +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_grpc_default(): + # A client should use the gRPC transport by default. + client = SystemPolicyV1Beta1Client( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance(client.transport, transports.SystemPolicyV1Beta1GrpcTransport,) + + +def test_system_policy_v1_beta1_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.SystemPolicyV1Beta1Transport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_system_policy_v1_beta1_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.binaryauthorization_v1beta1.services.system_policy_v1_beta1.transports.SystemPolicyV1Beta1Transport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.SystemPolicyV1Beta1Transport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ("get_system_policy",) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + +def test_system_policy_v1_beta1_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.binaryauthorization_v1beta1.services.system_policy_v1_beta1.transports.SystemPolicyV1Beta1Transport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SystemPolicyV1Beta1Transport( + 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_system_policy_v1_beta1_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.binaryauthorization_v1beta1.services.system_policy_v1_beta1.transports.SystemPolicyV1Beta1Transport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SystemPolicyV1Beta1Transport() + adc.assert_called_once() + + +def test_system_policy_v1_beta1_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) + SystemPolicyV1Beta1Client() + 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.SystemPolicyV1Beta1GrpcTransport, + transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, + ], +) +def test_system_policy_v1_beta1_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,grpc_helpers", + [ + (transports.SystemPolicyV1Beta1GrpcTransport, grpc_helpers), + (transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_system_policy_v1_beta1_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( + "binaryauthorization.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="binaryauthorization.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SystemPolicyV1Beta1GrpcTransport, + transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, + ], +) +def test_system_policy_v1_beta1_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_system_policy_v1_beta1_host_no_port(): + client = SystemPolicyV1Beta1Client( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="binaryauthorization.googleapis.com" + ), + ) + assert client.transport._host == "binaryauthorization.googleapis.com:443" + + +def test_system_policy_v1_beta1_host_with_port(): + client = SystemPolicyV1Beta1Client( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="binaryauthorization.googleapis.com:8000" + ), + ) + assert client.transport._host == "binaryauthorization.googleapis.com:8000" + + +def test_system_policy_v1_beta1_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SystemPolicyV1Beta1GrpcTransport( + 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_system_policy_v1_beta1_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SystemPolicyV1Beta1GrpcAsyncIOTransport( + 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.SystemPolicyV1Beta1GrpcTransport, + transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, + ], +) +def test_system_policy_v1_beta1_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.SystemPolicyV1Beta1GrpcTransport, + transports.SystemPolicyV1Beta1GrpcAsyncIOTransport, + ], +) +def test_system_policy_v1_beta1_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_policy_path(): + project = "squid" + expected = "projects/{project}/policy".format(project=project,) + actual = SystemPolicyV1Beta1Client.policy_path(project) + assert expected == actual + + +def test_parse_policy_path(): + expected = { + "project": "clam", + } + path = SystemPolicyV1Beta1Client.policy_path(**expected) + + # Check that the path construction is reversible. + actual = SystemPolicyV1Beta1Client.parse_policy_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = SystemPolicyV1Beta1Client.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = SystemPolicyV1Beta1Client.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = SystemPolicyV1Beta1Client.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder,) + actual = SystemPolicyV1Beta1Client.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = SystemPolicyV1Beta1Client.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = SystemPolicyV1Beta1Client.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization,) + actual = SystemPolicyV1Beta1Client.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = SystemPolicyV1Beta1Client.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = SystemPolicyV1Beta1Client.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project,) + actual = SystemPolicyV1Beta1Client.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = SystemPolicyV1Beta1Client.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = SystemPolicyV1Beta1Client.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format( + project=project, location=location, + ) + actual = SystemPolicyV1Beta1Client.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = SystemPolicyV1Beta1Client.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = SystemPolicyV1Beta1Client.parse_common_location_path(path) + assert expected == actual + + +def test_client_withDEFAULT_CLIENT_INFO(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.SystemPolicyV1Beta1Transport, "_prep_wrapped_messages" + ) as prep: + client = SystemPolicyV1Beta1Client( + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.SystemPolicyV1Beta1Transport, "_prep_wrapped_messages" + ) as prep: + transport_class = SystemPolicyV1Beta1Client.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = SystemPolicyV1Beta1AsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = SystemPolicyV1Beta1Client( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = SystemPolicyV1Beta1Client( + 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() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy