From 5d3b7a7402496ed13dca26c76880584c5abd81ee Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Wed, 1 Sep 2021 15:44:53 +0000 Subject: [PATCH 1/6] chore(python): group renovate prs (#88) --- .github/.OwlBot.lock.yaml | 2 +- renovate.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index b75186c..ef3cb34 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,3 @@ docker: image: gcr.io/repo-automation-bots/owlbot-python:latest - digest: sha256:d6761eec279244e57fe9d21f8343381a01d3632c034811a72f68b83119e58c69 + digest: sha256:1456ea2b3b523ccff5e13030acef56d1de28f21249c62aa0f196265880338fa7 diff --git a/renovate.json b/renovate.json index 9fa8816..c21036d 100644 --- a/renovate.json +++ b/renovate.json @@ -1,6 +1,7 @@ { "extends": [ "config:base", + "group:all", ":preserveSemverRanges", ":disableDependencyDashboard" ], From 368c29c1bc62f0e36bf2eaf694c3b7afc795ddde Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 2 Sep 2021 23:16:14 +0000 Subject: [PATCH 2/6] chore(python): rename default branch to main (#89) --- .github/.OwlBot.lock.yaml | 2 +- CONTRIBUTING.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index ef3cb34..c07f148 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,3 @@ docker: image: gcr.io/repo-automation-bots/owlbot-python:latest - digest: sha256:1456ea2b3b523ccff5e13030acef56d1de28f21249c62aa0f196265880338fa7 + digest: sha256:0ffe3bdd6c7159692df5f7744da74e5ef19966288a6bf76023e8e04e0c424d7d diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 18234d1..07e889e 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -113,9 +113,9 @@ Coding Style export GOOGLE_CLOUD_TESTING_BRANCH="main" By doing this, you are specifying the location of the most up-to-date - version of ``python-channel``. The the suggested remote name ``upstream`` - should point to the official ``googleapis`` checkout and the - the branch should be the main branch on that remote (``main``). + version of ``python-channel``. The + remote name ``upstream`` should point to the official ``googleapis`` + checkout and the branch should be the default branch on that remote (``main``). - This repository contains configuration for the `pre-commit `__ tool, which automates checking From d0cb72158d1b17109d4717dd3490041bf783f6b0 Mon Sep 17 00:00:00 2001 From: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com> Date: Tue, 7 Sep 2021 10:37:06 -0600 Subject: [PATCH 3/6] chore: reference main branch of google-cloud-python (#91) --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 0c20ed1..cd9ef9f 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,7 @@ order management, billing management, policy and authorization management, and c - `Product Documentation`_ .. |GA| image:: https://img.shields.io/badge/support-ga-gold.svg - :target: https://github.com/googleapis/google-cloud-python/blob/master/README.rst#general-availability + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#general-availability .. |pypi| image:: https://img.shields.io/pypi/v/google-cloud-channel.svg :target: https://pypi.org/project/google-cloud-channel/ .. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-channel.svg @@ -81,4 +81,4 @@ Next Steps APIs that we cover. .. _Cloud Channel API Product documentation: https://cloud.google.com/channel/docs -.. _README: https://github.com/googleapis/google-cloud-python/blob/master/README.rst \ No newline at end of file +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst \ No newline at end of file From d338a341187a09557c3ce3d412b3a73faa32bb37 Mon Sep 17 00:00:00 2001 From: Jeffrey Rennie Date: Tue, 21 Sep 2021 13:42:18 -0700 Subject: [PATCH 4/6] chore: relocate owl bot post processor (#93) chore: relocate owl bot post processor --- .github/.OwlBot.lock.yaml | 4 ++-- .github/.OwlBot.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index c07f148..2567653 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,3 @@ docker: - image: gcr.io/repo-automation-bots/owlbot-python:latest - digest: sha256:0ffe3bdd6c7159692df5f7744da74e5ef19966288a6bf76023e8e04e0c424d7d + image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest + digest: sha256:87eee22d276554e4e52863ec9b1cb6a7245815dfae20439712bf644348215a5a diff --git a/.github/.OwlBot.yaml b/.github/.OwlBot.yaml index af8f560..241b157 100644 --- a/.github/.OwlBot.yaml +++ b/.github/.OwlBot.yaml @@ -13,7 +13,7 @@ # limitations under the License. docker: - image: gcr.io/repo-automation-bots/owlbot-python:latest + image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest deep-remove-regex: - /owl-bot-staging From 2bb2d8987da8a6138bef45c5fd278cb25235cfa7 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 23 Sep 2021 09:52:11 +0000 Subject: [PATCH 5/6] feat: add ImportCustomer (#90) - [ ] Regenerate this pull request now. PiperOrigin-RevId: 394721709 Source-Link: https://github.com/googleapis/googleapis/commit/bf57b2c88187c599bf669005d1d2ce80a40780df Source-Link: https://github.com/googleapis/googleapis-gen/commit/699e6d5fdcb12daac24587c0643016855ccb2e16 --- google/cloud/channel/__init__.py | 2 + google/cloud/channel_v1/__init__.py | 2 + google/cloud/channel_v1/gapic_metadata.json | 10 ++ .../cloud_channel_service/async_client.py | 65 +++++++ .../services/cloud_channel_service/client.py | 66 +++++++ .../cloud_channel_service/transports/base.py | 12 ++ .../cloud_channel_service/transports/grpc.py | 42 +++++ .../transports/grpc_asyncio.py | 42 +++++ google/cloud/channel_v1/types/__init__.py | 2 + google/cloud/channel_v1/types/customers.py | 8 +- google/cloud/channel_v1/types/service.py | 48 ++++++ scripts/fixup_channel_v1_keywords.py | 1 + .../channel_v1/test_cloud_channel_service.py | 163 ++++++++++++++++++ 13 files changed, 461 insertions(+), 2 deletions(-) diff --git a/google/cloud/channel/__init__.py b/google/cloud/channel/__init__.py index fbdc106..74333e9 100644 --- a/google/cloud/channel/__init__.py +++ b/google/cloud/channel/__init__.py @@ -77,6 +77,7 @@ from google.cloud.channel_v1.types.service import GetChannelPartnerLinkRequest from google.cloud.channel_v1.types.service import GetCustomerRequest from google.cloud.channel_v1.types.service import GetEntitlementRequest +from google.cloud.channel_v1.types.service import ImportCustomerRequest from google.cloud.channel_v1.types.service import ListChannelPartnerLinksRequest from google.cloud.channel_v1.types.service import ListChannelPartnerLinksResponse from google.cloud.channel_v1.types.service import ListCustomersRequest @@ -176,6 +177,7 @@ "GetChannelPartnerLinkRequest", "GetCustomerRequest", "GetEntitlementRequest", + "ImportCustomerRequest", "ListChannelPartnerLinksRequest", "ListChannelPartnerLinksResponse", "ListCustomersRequest", diff --git a/google/cloud/channel_v1/__init__.py b/google/cloud/channel_v1/__init__.py index 73fb429..fec98e9 100644 --- a/google/cloud/channel_v1/__init__.py +++ b/google/cloud/channel_v1/__init__.py @@ -71,6 +71,7 @@ from .types.service import GetChannelPartnerLinkRequest from .types.service import GetCustomerRequest from .types.service import GetEntitlementRequest +from .types.service import ImportCustomerRequest from .types.service import ListChannelPartnerLinksRequest from .types.service import ListChannelPartnerLinksResponse from .types.service import ListCustomersRequest @@ -146,6 +147,7 @@ "GetChannelPartnerLinkRequest", "GetCustomerRequest", "GetEntitlementRequest", + "ImportCustomerRequest", "ListChannelPartnerLinksRequest", "ListChannelPartnerLinksResponse", "ListCustomersRequest", diff --git a/google/cloud/channel_v1/gapic_metadata.json b/google/cloud/channel_v1/gapic_metadata.json index e0d0f40..9c71a5f 100644 --- a/google/cloud/channel_v1/gapic_metadata.json +++ b/google/cloud/channel_v1/gapic_metadata.json @@ -75,6 +75,11 @@ "get_entitlement" ] }, + "ImportCustomer": { + "methods": [ + "import_customer" + ] + }, "ListChannelPartnerLinks": { "methods": [ "list_channel_partner_links" @@ -250,6 +255,11 @@ "get_entitlement" ] }, + "ImportCustomer": { + "methods": [ + "import_customer" + ] + }, "ListChannelPartnerLinks": { "methods": [ "list_channel_partner_links" diff --git a/google/cloud/channel_v1/services/cloud_channel_service/async_client.py b/google/cloud/channel_v1/services/cloud_channel_service/async_client.py index 8325e23..6e1567e 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/async_client.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/async_client.py @@ -630,6 +630,71 @@ async def delete_customer( request, retry=retry, timeout=timeout, metadata=metadata, ) + async def import_customer( + self, + request: service.ImportCustomerRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customers.Customer: + r"""Imports a [Customer][google.cloud.channel.v1.Customer] from the + Cloud Identity associated with the provided Cloud Identity ID or + domain before a TransferEntitlements call. If a linked Customer + already exists and overwrite_if_exists is true, it will update + that Customer's data. + + Possible error codes: + + - PERMISSION_DENIED: The reseller account making the request is + different from the reseller account in the API request. + - NOT_FOUND: Cloud Identity doesn't exist or was deleted. + - INVALID_ARGUMENT: Required parameters are missing, or the + auth_token is expired or invalid. + - ALREADY_EXISTS: A customer already exists and has conflicting + critical fields. Requires an overwrite. + + Return value: The [Customer][google.cloud.channel.v1.Customer]. + + Args: + request (:class:`google.cloud.channel_v1.types.ImportCustomerRequest`): + The request object. Request message for + [CloudChannelService.ImportCustomer][google.cloud.channel.v1.CloudChannelService.ImportCustomer] + 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.channel_v1.types.Customer: + Entity representing a customer of a + reseller or distributor. + + """ + # Create or coerce a protobuf request object. + request = service.ImportCustomerRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.import_customer, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + async def provision_cloud_identity( self, request: service.ProvisionCloudIdentityRequest = None, diff --git a/google/cloud/channel_v1/services/cloud_channel_service/client.py b/google/cloud/channel_v1/services/cloud_channel_service/client.py index cafe721..1148c96 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/client.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/client.py @@ -863,6 +863,72 @@ def delete_customer( request, retry=retry, timeout=timeout, metadata=metadata, ) + def import_customer( + self, + request: service.ImportCustomerRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> customers.Customer: + r"""Imports a [Customer][google.cloud.channel.v1.Customer] from the + Cloud Identity associated with the provided Cloud Identity ID or + domain before a TransferEntitlements call. If a linked Customer + already exists and overwrite_if_exists is true, it will update + that Customer's data. + + Possible error codes: + + - PERMISSION_DENIED: The reseller account making the request is + different from the reseller account in the API request. + - NOT_FOUND: Cloud Identity doesn't exist or was deleted. + - INVALID_ARGUMENT: Required parameters are missing, or the + auth_token is expired or invalid. + - ALREADY_EXISTS: A customer already exists and has conflicting + critical fields. Requires an overwrite. + + Return value: The [Customer][google.cloud.channel.v1.Customer]. + + Args: + request (google.cloud.channel_v1.types.ImportCustomerRequest): + The request object. Request message for + [CloudChannelService.ImportCustomer][google.cloud.channel.v1.CloudChannelService.ImportCustomer] + 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.channel_v1.types.Customer: + Entity representing a customer of a + reseller or distributor. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a service.ImportCustomerRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, service.ImportCustomerRequest): + request = service.ImportCustomerRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_customer] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + def provision_cloud_identity( self, request: service.ProvisionCloudIdentityRequest = None, diff --git a/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py b/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py index 70cc3bb..22509b7 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py @@ -179,6 +179,9 @@ def _prep_wrapped_messages(self, client_info): self.delete_customer: gapic_v1.method.wrap_method( self.delete_customer, default_timeout=None, client_info=client_info, ), + self.import_customer: gapic_v1.method.wrap_method( + self.import_customer, default_timeout=None, client_info=client_info, + ), self.provision_cloud_identity: gapic_v1.method.wrap_method( self.provision_cloud_identity, default_timeout=60.0, @@ -355,6 +358,15 @@ def delete_customer( ]: raise NotImplementedError() + @property + def import_customer( + self, + ) -> Callable[ + [service.ImportCustomerRequest], + Union[customers.Customer, Awaitable[customers.Customer]], + ]: + raise NotImplementedError() + @property def provision_cloud_identity( self, diff --git a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py index 188afe1..2dde5ad 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py @@ -511,6 +511,48 @@ def delete_customer( ) return self._stubs["delete_customer"] + @property + def import_customer( + self, + ) -> Callable[[service.ImportCustomerRequest], customers.Customer]: + r"""Return a callable for the import customer method over gRPC. + + Imports a [Customer][google.cloud.channel.v1.Customer] from the + Cloud Identity associated with the provided Cloud Identity ID or + domain before a TransferEntitlements call. If a linked Customer + already exists and overwrite_if_exists is true, it will update + that Customer's data. + + Possible error codes: + + - PERMISSION_DENIED: The reseller account making the request is + different from the reseller account in the API request. + - NOT_FOUND: Cloud Identity doesn't exist or was deleted. + - INVALID_ARGUMENT: Required parameters are missing, or the + auth_token is expired or invalid. + - ALREADY_EXISTS: A customer already exists and has conflicting + critical fields. Requires an overwrite. + + Return value: The [Customer][google.cloud.channel.v1.Customer]. + + Returns: + Callable[[~.ImportCustomerRequest], + ~.Customer]: + 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 "import_customer" not in self._stubs: + self._stubs["import_customer"] = self.grpc_channel.unary_unary( + "/google.cloud.channel.v1.CloudChannelService/ImportCustomer", + request_serializer=service.ImportCustomerRequest.serialize, + response_deserializer=customers.Customer.deserialize, + ) + return self._stubs["import_customer"] + @property def provision_cloud_identity( self, diff --git a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py index e58dfc7..a67eb66 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py @@ -518,6 +518,48 @@ def delete_customer( ) return self._stubs["delete_customer"] + @property + def import_customer( + self, + ) -> Callable[[service.ImportCustomerRequest], Awaitable[customers.Customer]]: + r"""Return a callable for the import customer method over gRPC. + + Imports a [Customer][google.cloud.channel.v1.Customer] from the + Cloud Identity associated with the provided Cloud Identity ID or + domain before a TransferEntitlements call. If a linked Customer + already exists and overwrite_if_exists is true, it will update + that Customer's data. + + Possible error codes: + + - PERMISSION_DENIED: The reseller account making the request is + different from the reseller account in the API request. + - NOT_FOUND: Cloud Identity doesn't exist or was deleted. + - INVALID_ARGUMENT: Required parameters are missing, or the + auth_token is expired or invalid. + - ALREADY_EXISTS: A customer already exists and has conflicting + critical fields. Requires an overwrite. + + Return value: The [Customer][google.cloud.channel.v1.Customer]. + + Returns: + Callable[[~.ImportCustomerRequest], + Awaitable[~.Customer]]: + 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 "import_customer" not in self._stubs: + self._stubs["import_customer"] = self.grpc_channel.unary_unary( + "/google.cloud.channel.v1.CloudChannelService/ImportCustomer", + request_serializer=service.ImportCustomerRequest.serialize, + response_deserializer=customers.Customer.deserialize, + ) + return self._stubs["import_customer"] + @property def provision_cloud_identity( self, diff --git a/google/cloud/channel_v1/types/__init__.py b/google/cloud/channel_v1/types/__init__.py index 27aadd3..368114c 100644 --- a/google/cloud/channel_v1/types/__init__.py +++ b/google/cloud/channel_v1/types/__init__.py @@ -80,6 +80,7 @@ GetChannelPartnerLinkRequest, GetCustomerRequest, GetEntitlementRequest, + ImportCustomerRequest, ListChannelPartnerLinksRequest, ListChannelPartnerLinksResponse, ListCustomersRequest, @@ -180,6 +181,7 @@ "GetChannelPartnerLinkRequest", "GetCustomerRequest", "GetEntitlementRequest", + "ImportCustomerRequest", "ListChannelPartnerLinksRequest", "ListChannelPartnerLinksResponse", "ListCustomersRequest", diff --git a/google/cloud/channel_v1/types/customers.py b/google/cloud/channel_v1/types/customers.py index 49df85e..b6d3b7f 100644 --- a/google/cloud/channel_v1/types/customers.py +++ b/google/cloud/channel_v1/types/customers.py @@ -50,7 +50,8 @@ class Customer(proto.Message): will receive a notification with credentials when you create an admin.google.com account. Secondary emails are also recovery email - addresses. + addresses. Alternate emails are optional when + you create Team customers. domain (str): Required. The customer's primary domain. Must match the primary contact email's domain. @@ -100,8 +101,10 @@ class ContactInfo(proto.Message): Attributes: first_name (str): The customer account contact's first name. + Optional for Team customers. last_name (str): The customer account contact's last name. + Optional for Team customers. display_name (str): Output only. The customer account contact's display name, formatted as a combination of the @@ -110,7 +113,8 @@ class ContactInfo(proto.Message): The customer account's contact email. Required for entitlements that create admin.google.com accounts, and serves as the - customer's username for those accounts. + customer's username for those accounts. Use this + email to invite Team customers. title (str): Optional. The customer account contact's job title. diff --git a/google/cloud/channel_v1/types/service.py b/google/cloud/channel_v1/types/service.py index 8e642ab..f578689 100644 --- a/google/cloud/channel_v1/types/service.py +++ b/google/cloud/channel_v1/types/service.py @@ -38,6 +38,7 @@ "CreateCustomerRequest", "UpdateCustomerRequest", "DeleteCustomerRequest", + "ImportCustomerRequest", "ProvisionCloudIdentityRequest", "ListEntitlementsRequest", "ListEntitlementsResponse", @@ -259,6 +260,53 @@ class DeleteCustomerRequest(proto.Message): name = proto.Field(proto.STRING, number=1,) +class ImportCustomerRequest(proto.Message): + r"""Request message for + [CloudChannelService.ImportCustomer][google.cloud.channel.v1.CloudChannelService.ImportCustomer] + + Attributes: + domain (str): + Required. Customer domain. + cloud_identity_id (str): + Required. Customer's Cloud Identity ID + parent (str): + Required. The resource name of the reseller's account. + Parent takes the format: accounts/{account_id} or + accounts/{account_id}/channelPartnerLinks/{channel_partner_id} + auth_token (str): + Optional. The super admin of the resold + customer generates this token to authorize a + reseller to access their Cloud Identity and + purchase entitlements on their behalf. You can + omit this token after authorization. See + https://support.google.com/a/answer/7643790 for + more details. + overwrite_if_exists (bool): + Required. Choose to overwrite an existing + customer if found. This must be set to true if + there is an existing customer with a conflicting + region code or domain. + channel_partner_id (str): + Optional. Cloud Identity ID of a channel + partner who will be the direct reseller for the + customer's order. This field is required for + 2-tier transfer scenarios and can be provided + via the request Parent binding as well. + customer (str): + Optional. Specifies the customer that will receive imported + Cloud Identity information. Format: + accounts/{account_id}/customers/{customer_id} + """ + + domain = proto.Field(proto.STRING, number=2, oneof="customer_identity",) + cloud_identity_id = proto.Field(proto.STRING, number=3, oneof="customer_identity",) + parent = proto.Field(proto.STRING, number=1,) + auth_token = proto.Field(proto.STRING, number=4,) + overwrite_if_exists = proto.Field(proto.BOOL, number=5,) + channel_partner_id = proto.Field(proto.STRING, number=6,) + customer = proto.Field(proto.STRING, number=7,) + + class ProvisionCloudIdentityRequest(proto.Message): r"""Request message for [CloudChannelService.ProvisionCloudIdentity][google.cloud.channel.v1.CloudChannelService.ProvisionCloudIdentity] diff --git a/scripts/fixup_channel_v1_keywords.py b/scripts/fixup_channel_v1_keywords.py index 2d4cfca..a21c4e8 100644 --- a/scripts/fixup_channel_v1_keywords.py +++ b/scripts/fixup_channel_v1_keywords.py @@ -52,6 +52,7 @@ class channelCallTransformer(cst.CSTTransformer): 'get_channel_partner_link': ('name', 'view', ), 'get_customer': ('name', ), 'get_entitlement': ('name', ), + 'import_customer': ('domain', 'cloud_identity_id', 'parent', 'overwrite_if_exists', 'auth_token', 'channel_partner_id', 'customer', ), 'list_channel_partner_links': ('parent', 'page_size', 'page_token', 'view', ), 'list_customers': ('parent', 'page_size', 'page_token', ), 'list_entitlements': ('parent', 'page_size', 'page_token', ), diff --git a/tests/unit/gapic/channel_v1/test_cloud_channel_service.py b/tests/unit/gapic/channel_v1/test_cloud_channel_service.py index 4a5be71..1f6cc1f 100644 --- a/tests/unit/gapic/channel_v1/test_cloud_channel_service.py +++ b/tests/unit/gapic/channel_v1/test_cloud_channel_service.py @@ -1719,6 +1719,168 @@ async def test_delete_customer_flattened_error_async(): ) +def test_import_customer( + transport: str = "grpc", request_type=service.ImportCustomerRequest +): + client = CloudChannelServiceClient( + 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.import_customer), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = customers.Customer( + name="name_value", + org_display_name="org_display_name_value", + alternate_email="alternate_email_value", + domain="domain_value", + cloud_identity_id="cloud_identity_id_value", + language_code="language_code_value", + channel_partner_id="channel_partner_id_value", + ) + response = client.import_customer(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.ImportCustomerRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, customers.Customer) + assert response.name == "name_value" + assert response.org_display_name == "org_display_name_value" + assert response.alternate_email == "alternate_email_value" + assert response.domain == "domain_value" + assert response.cloud_identity_id == "cloud_identity_id_value" + assert response.language_code == "language_code_value" + assert response.channel_partner_id == "channel_partner_id_value" + + +def test_import_customer_from_dict(): + test_import_customer(request_type=dict) + + +def test_import_customer_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 = CloudChannelServiceClient( + 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.import_customer), "__call__") as call: + client.import_customer() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == service.ImportCustomerRequest() + + +@pytest.mark.asyncio +async def test_import_customer_async( + transport: str = "grpc_asyncio", request_type=service.ImportCustomerRequest +): + client = CloudChannelServiceAsyncClient( + 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.import_customer), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + customers.Customer( + name="name_value", + org_display_name="org_display_name_value", + alternate_email="alternate_email_value", + domain="domain_value", + cloud_identity_id="cloud_identity_id_value", + language_code="language_code_value", + channel_partner_id="channel_partner_id_value", + ) + ) + response = await client.import_customer(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == service.ImportCustomerRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, customers.Customer) + assert response.name == "name_value" + assert response.org_display_name == "org_display_name_value" + assert response.alternate_email == "alternate_email_value" + assert response.domain == "domain_value" + assert response.cloud_identity_id == "cloud_identity_id_value" + assert response.language_code == "language_code_value" + assert response.channel_partner_id == "channel_partner_id_value" + + +@pytest.mark.asyncio +async def test_import_customer_async_from_dict(): + await test_import_customer_async(request_type=dict) + + +def test_import_customer_field_headers(): + client = CloudChannelServiceClient( + 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.ImportCustomerRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_customer), "__call__") as call: + call.return_value = customers.Customer() + client.import_customer(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_import_customer_field_headers_async(): + client = CloudChannelServiceAsyncClient( + 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.ImportCustomerRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_customer), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(customers.Customer()) + await client.import_customer(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + def test_provision_cloud_identity( transport: str = "grpc", request_type=service.ProvisionCloudIdentityRequest ): @@ -7367,6 +7529,7 @@ def test_cloud_channel_service_base_transport(): "create_customer", "update_customer", "delete_customer", + "import_customer", "provision_cloud_identity", "list_entitlements", "list_transferable_skus", From d72814d5be9df4184a8f65a285a46c3a1743177c Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 23 Sep 2021 08:53:46 -0600 Subject: [PATCH 6/6] chore: release 1.3.0 (#94) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b90506..1779b6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.3.0](https://www.github.com/googleapis/python-channel/compare/v1.2.3...v1.3.0) (2021-09-23) + + +### Features + +* add ImportCustomer ([#90](https://www.github.com/googleapis/python-channel/issues/90)) ([2bb2d89](https://www.github.com/googleapis/python-channel/commit/2bb2d8987da8a6138bef45c5fd278cb25235cfa7)) + ### [1.2.3](https://www.github.com/googleapis/python-channel/compare/v1.2.2...v1.2.3) (2021-08-31) diff --git a/setup.py b/setup.py index cf08098..8fee988 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ import os import setuptools # type: ignore -version = "1.2.3" +version = "1.3.0" package_root = os.path.abspath(os.path.dirname(__file__))