From 0fe5b638e45e711d25f55664689a9baf4d12dc57 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Thu, 25 Feb 2021 11:28:20 -0800 Subject: [PATCH] feat: publish new fields for CMEK (#222) * changes without context autosynth cannot find the source of changes triggered by earlier changes in this repository, or by version upgrades to tools such as linters. * Bump gapic-generator to 2.6.1. - Fix a scenario where generator attempts to assign a string to an integer in tests by using a separate value generator in test generation PiperOrigin-RevId: 336931287 Source-Author: Google APIs Source-Date: Tue Oct 13 12:29:21 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 3a935fab757e09c72afd4aa121147a4c97dccc3e Source-Link: https://github.com/googleapis/googleapis/commit/3a935fab757e09c72afd4aa121147a4c97dccc3e * chore: update grpc dependency to v1.33.1 PiperOrigin-RevId: 338646463 Source-Author: Google APIs Source-Date: Fri Oct 23 03:57:15 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: 20b11dfe4538cd5da7b4c3dd7d2bf5b9922ff3ed Source-Link: https://github.com/googleapis/googleapis/commit/20b11dfe4538cd5da7b4c3dd7d2bf5b9922ff3ed * feat:Update BigtableTableAdmin GetIamPolicy to include the additional binding for Backup. feat:Change DeleteAppProfileRequest.ignore_warnings to REQUIRED. PiperOrigin-RevId: 339464550 Source-Author: Google APIs Source-Date: Wed Oct 28 08:32:48 2020 -0700 Source-Repo: googleapis/googleapis Source-Sha: ccd6462d31e6422fd188b6590aa8d0ad03e7d9a3 Source-Link: https://github.com/googleapis/googleapis/commit/ccd6462d31e6422fd188b6590aa8d0ad03e7d9a3 * feat: migrate bigtable retry/timeout settings to gRPC's service configs Committer: @miraleung PiperOrigin-RevId: 346894665 Source-Author: Google APIs Source-Date: Thu Dec 10 16:55:31 2020 -0800 Source-Repo: googleapis/googleapis Source-Sha: cbbd3170bcf217e36ae72f4ac522449bf861346f Source-Link: https://github.com/googleapis/googleapis/commit/cbbd3170bcf217e36ae72f4ac522449bf861346f * chore: migrate bigtable to the Python microgenerator PiperOrigin-RevId: 356992836 Source-Author: Google APIs Source-Date: Thu Feb 11 09:33:53 2021 -0800 Source-Repo: googleapis/googleapis Source-Sha: 1e0c7413684ca6f6322620ecfc0d3e0352933dc1 Source-Link: https://github.com/googleapis/googleapis/commit/1e0c7413684ca6f6322620ecfc0d3e0352933dc1 * chore: migrate StreetView to the {Java,Python} microgenerators Committer: @miraleung PiperOrigin-RevId: 357863594 Source-Author: Google APIs Source-Date: Tue Feb 16 20:19:58 2021 -0800 Source-Repo: googleapis/googleapis Source-Sha: 8ca872ced04c96c05a36db3d2113d568ac814be8 Source-Link: https://github.com/googleapis/googleapis/commit/8ca872ced04c96c05a36db3d2113d568ac814be8 * feat: Publish new fields to support Customer Managed Encryption Keys (CMEK) on the existing Cloud Bigtable service methods. PiperOrigin-RevId: 359130387 Source-Author: Google APIs Source-Date: Tue Feb 23 14:08:20 2021 -0800 Source-Repo: googleapis/googleapis Source-Sha: eabec5a21219401bad79e1cc7d900c1658aee5fd Source-Link: https://github.com/googleapis/googleapis/commit/eabec5a21219401bad79e1cc7d900c1658aee5fd * fix: Use rules_gapic to v0.5.0. Fixes handling parameters with spaces. Committer: @alexander-fenster PiperOrigin-RevId: 359364666 Source-Author: Google APIs Source-Date: Wed Feb 24 14:01:05 2021 -0800 Source-Repo: googleapis/googleapis Source-Sha: c06bbe28cc7287a55bf7926ee48da2565854de7f Source-Link: https://github.com/googleapis/googleapis/commit/c06bbe28cc7287a55bf7926ee48da2565854de7f * fix noxfile Co-authored-by: Kristen O'Leary --- .gitignore | 4 +- .kokoro/build.sh | 10 -- google/cloud/bigtable_admin_v2/__init__.py | 6 +- .../bigtable_admin_v2/proto/instance.proto | 29 +++++- .../cloud/bigtable_admin_v2/proto/table.proto | 75 +++++++++++++- .../bigtable_instance_admin/async_client.py | 4 + .../bigtable_instance_admin/client.py | 21 ++++ .../bigtable_table_admin/async_client.py | 6 ++ .../services/bigtable_table_admin/client.py | 26 +++++ .../cloud/bigtable_admin_v2/types/__init__.py | 2 + .../cloud/bigtable_admin_v2/types/instance.py | 29 +++++- google/cloud/bigtable_admin_v2/types/table.py | 64 +++++++++++- scripts/fixup_bigtable_admin_v2_keywords.py | 2 +- synth.metadata | 86 ++++++++-------- .../test_bigtable_instance_admin.py | 61 +++++++++--- .../test_bigtable_table_admin.py | 97 +++++++++++++------ 16 files changed, 407 insertions(+), 115 deletions(-) diff --git a/.gitignore b/.gitignore index b4243ced7..b9daa52f1 100644 --- a/.gitignore +++ b/.gitignore @@ -50,10 +50,8 @@ docs.metadata # Virtual environment env/ - -# Test logs coverage.xml -*sponge_log.xml +sponge_log.xml # System test environment variables. system_tests/local_test_setup diff --git a/.kokoro/build.sh b/.kokoro/build.sh index 9773bfca7..76d9329ba 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -40,16 +40,6 @@ python3 -m pip uninstall --yes --quiet nox-automation python3 -m pip install --upgrade --quiet nox python3 -m nox --version -# If this is a continuous build, send the test log to the FlakyBot. -# See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. -if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]]; then - cleanup() { - chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot - $KOKORO_GFILE_DIR/linux_amd64/flakybot - } - trap cleanup EXIT HUP -fi - # If NOX_SESSION is set, it only runs the specified session, # otherwise run all the sessions. if [[ -n "${NOX_SESSION:-}" ]]; then diff --git a/google/cloud/bigtable_admin_v2/__init__.py b/google/cloud/bigtable_admin_v2/__init__.py index 423742502..79a9bea68 100644 --- a/google/cloud/bigtable_admin_v2/__init__.py +++ b/google/cloud/bigtable_admin_v2/__init__.py @@ -76,6 +76,7 @@ from .types.table import Backup from .types.table import BackupInfo from .types.table import ColumnFamily +from .types.table import EncryptionInfo from .types.table import GcRule from .types.table import RestoreInfo from .types.table import RestoreSourceType @@ -87,7 +88,7 @@ "AppProfile", "Backup", "BackupInfo", - "BigtableInstanceAdminClient", + "BigtableTableAdminClient", "CheckConsistencyRequest", "CheckConsistencyResponse", "Cluster", @@ -109,6 +110,7 @@ "DeleteSnapshotRequest", "DeleteTableRequest", "DropRowRangeRequest", + "EncryptionInfo", "GcRule", "GenerateConsistencyTokenRequest", "GenerateConsistencyTokenResponse", @@ -149,5 +151,5 @@ "UpdateBackupRequest", "UpdateClusterMetadata", "UpdateInstanceMetadata", - "BigtableTableAdminClient", + "BigtableInstanceAdminClient", ) diff --git a/google/cloud/bigtable_admin_v2/proto/instance.proto b/google/cloud/bigtable_admin_v2/proto/instance.proto index 2086f9707..d590788b2 100644 --- a/google/cloud/bigtable_admin_v2/proto/instance.proto +++ b/google/cloud/bigtable_admin_v2/proto/instance.proto @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC. +// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,7 +11,6 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// syntax = "proto3"; @@ -28,6 +27,10 @@ option java_outer_classname = "InstanceProto"; option java_package = "com.google.bigtable.admin.v2"; option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2"; option ruby_package = "Google::Cloud::Bigtable::Admin::V2"; +option (google.api.resource_definition) = { + type: "cloudkms.googleapis.com/CryptoKey" + pattern: "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}" +}; // A collection of Bigtable [Tables][google.bigtable.admin.v2.Table] and // the resources that serve them. @@ -113,6 +116,22 @@ message Cluster { pattern: "projects/{project}/instances/{instance}/clusters/{cluster}" }; + // Cloud Key Management Service (Cloud KMS) settings for a CMEK-protected + // cluster. + message EncryptionConfig { + // Describes the Cloud KMS encryption key that will be used to protect the + // destination Bigtable cluster. The requirements for this key are: + // 1) The Cloud Bigtable service account associated with the project that + // contains this cluster must be granted the + // `cloudkms.cryptoKeyEncrypterDecrypter` role on the CMEK key. + // 2) Only regional keys can be used and the region of the CMEK key must + // match the region of the cluster. + // 3) All clusters within an instance must use the same CMEK key. + string kms_key_name = 1 [(google.api.resource_reference) = { + type: "cloudkms.googleapis.com/CryptoKey" + }]; + } + // Possible states of a cluster. enum State { // The state of the cluster could not be determined. @@ -162,6 +181,10 @@ message Cluster { // The type of storage used by this cluster to serve its // parent instance's tables, unless explicitly overridden. StorageType default_storage_type = 5; + + // Immutable. The encryption configuration for CMEK-protected clusters. + EncryptionConfig encryption_config = 6 + [(google.api.field_behavior) = IMMUTABLE]; } // A configuration object describing how Cloud Bigtable should treat traffic @@ -194,7 +217,7 @@ message AppProfile { // (`OutputOnly`) // The unique name of the app profile. Values are of the form - // `projects//instances//appProfiles/[_a-zA-Z0-9][-_.a-zA-Z0-9]*`. + // `projects/{project}/instances/{instance}/appProfiles/[_a-zA-Z0-9][-_.a-zA-Z0-9]*`. string name = 1; // Strongly validated etag for optimistic concurrency control. Preserve the diff --git a/google/cloud/bigtable_admin_v2/proto/table.proto b/google/cloud/bigtable_admin_v2/proto/table.proto index e85ca8ca9..a5578225e 100644 --- a/google/cloud/bigtable_admin_v2/proto/table.proto +++ b/google/cloud/bigtable_admin_v2/proto/table.proto @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; +import "google/rpc/status.proto"; option csharp_namespace = "Google.Cloud.Bigtable.Admin.V2"; option go_package = "google.golang.org/genproto/googleapis/bigtable/admin/v2;admin"; @@ -28,6 +29,10 @@ option java_outer_classname = "TableProto"; option java_package = "com.google.bigtable.admin.v2"; option php_namespace = "Google\\Cloud\\Bigtable\\Admin\\V2"; option ruby_package = "Google::Cloud::Bigtable::Admin::V2"; +option (google.api.resource_definition) = { + type: "cloudkms.googleapis.com/CryptoKeyVersion" + pattern: "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}/cryptoKeyVersions/{crypto_key_version}" +}; // Indicates the type of the restore source. enum RestoreSourceType { @@ -92,6 +97,14 @@ message Table { // Output only. The state of replication for the table in this cluster. ReplicationState replication_state = 1; + + // Output only. The encryption information for the table in this cluster. + // If the encryption key protecting this resource is customer managed, then + // its version can be rotated in Cloud Key Management Service (Cloud KMS). + // The primary version of the key and its status will be reflected here when + // changes propagate from Cloud KMS. + repeated EncryptionInfo encryption_info = 2 + [(google.api.field_behavior) = OUTPUT_ONLY]; } // Possible timestamp granularities to use when keeping multiple versions @@ -120,12 +133,15 @@ message Table { // state. REPLICATION_VIEW = 3; + // Only populates 'name' and fields related to the table's encryption state. + ENCRYPTION_VIEW = 5; + // Populates all fields. FULL = 4; } - // Output only. The unique name of the table. Values are of the form - // `projects//instances//tables/[_a-zA-Z0-9][-_.a-zA-Z0-9]*`. + // The unique name of the table. Values are of the form + // `projects/{project}/instances/{instance}/tables/[_a-zA-Z0-9][-_.a-zA-Z0-9]*`. // Views: `NAME_ONLY`, `SCHEMA_VIEW`, `REPLICATION_VIEW`, `FULL` string name = 1; @@ -133,7 +149,7 @@ message Table { // If it could not be determined whether or not the table has data in a // particular cluster (for example, if its zone is unavailable), then // there will be an entry for the cluster with UNKNOWN `replication_status`. - // Views: `REPLICATION_VIEW`, `FULL` + // Views: `REPLICATION_VIEW`, `ENCRYPTION_VIEW`, `FULL` map cluster_states = 2; // (`CreationOnly`) @@ -196,6 +212,51 @@ message GcRule { } } +// Encryption information for a given resource. +// If this resource is protected with customer managed encryption, the in-use +// Cloud Key Management Service (Cloud KMS) key version is specified along with +// its status. +message EncryptionInfo { + // Possible encryption types for a resource. + enum EncryptionType { + // Encryption type was not specified, though data at rest remains encrypted. + ENCRYPTION_TYPE_UNSPECIFIED = 0; + + // The data backing this resource is encrypted at rest with a key that is + // fully managed by Google. No key version or status will be populated. + // This is the default state. + GOOGLE_DEFAULT_ENCRYPTION = 1; + + // The data backing this resource is encrypted at rest with a key that is + // managed by the customer. + // The in-use version of the key and its status are populated for + // CMEK-protected tables. + // CMEK-protected backups are pinned to the key version that was in use at + // the time the backup was taken. This key version is populated but its + // status is not tracked and is reported as `UNKNOWN`. + CUSTOMER_MANAGED_ENCRYPTION = 2; + } + + // Output only. The type of encryption used to protect this resource. + EncryptionType encryption_type = 3 + [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. The status of encrypt/decrypt calls on underlying data for + // this resource. Regardless of status, the existing data is always encrypted + // at rest. + google.rpc.Status encryption_status = 4 + [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. The version of the Cloud KMS key specified in the parent + // cluster that is in use for the data underlying this table. + string kms_key_version = 2 [ + (google.api.field_behavior) = OUTPUT_ONLY, + (google.api.resource_reference) = { + type: "cloudkms.googleapis.com/CryptoKeyVersion" + } + ]; +} + // A snapshot of a table at a particular time. A snapshot can be used as a // checkpoint for data restoration or a data source for a new table. // @@ -225,7 +286,7 @@ message Snapshot { // Output only. The unique name of the snapshot. // Values are of the form - // `projects//instances//clusters//snapshots/`. + // `projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}`. string name = 1; // Output only. The source table at the time the snapshot was taken. @@ -318,6 +379,10 @@ message Backup { // Output only. The current state of the backup. State state = 7 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. The encryption information for the backup. + EncryptionInfo encryption_info = 9 + [(google.api.field_behavior) = OUTPUT_ONLY]; } // Information about a backup. diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/async_client.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/async_client.py index 4df47ff4a..d375f3280 100644 --- a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/async_client.py +++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/async_client.py @@ -62,6 +62,10 @@ class BigtableInstanceAdminAsyncClient: ) cluster_path = staticmethod(BigtableInstanceAdminClient.cluster_path) parse_cluster_path = staticmethod(BigtableInstanceAdminClient.parse_cluster_path) + crypto_key_path = staticmethod(BigtableInstanceAdminClient.crypto_key_path) + parse_crypto_key_path = staticmethod( + BigtableInstanceAdminClient.parse_crypto_key_path + ) instance_path = staticmethod(BigtableInstanceAdminClient.instance_path) parse_instance_path = staticmethod(BigtableInstanceAdminClient.parse_instance_path) diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py index d7b1a778f..fc161479b 100644 --- a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py +++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py @@ -201,6 +201,27 @@ def parse_cluster_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def crypto_key_path( + project: str, location: str, key_ring: str, crypto_key: str, + ) -> str: + """Return a fully-qualified crypto_key string.""" + return "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}".format( + project=project, + location=location, + key_ring=key_ring, + crypto_key=crypto_key, + ) + + @staticmethod + def parse_crypto_key_path(path: str) -> Dict[str, str]: + """Parse a crypto_key path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/keyRings/(?P.+?)/cryptoKeys/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def instance_path(project: str, instance: str,) -> str: """Return a fully-qualified instance string.""" diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/async_client.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/async_client.py index 19e9ee827..5aca2d377 100644 --- a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/async_client.py +++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/async_client.py @@ -61,6 +61,12 @@ class BigtableTableAdminAsyncClient: parse_backup_path = staticmethod(BigtableTableAdminClient.parse_backup_path) cluster_path = staticmethod(BigtableTableAdminClient.cluster_path) parse_cluster_path = staticmethod(BigtableTableAdminClient.parse_cluster_path) + crypto_key_version_path = staticmethod( + BigtableTableAdminClient.crypto_key_version_path + ) + parse_crypto_key_version_path = staticmethod( + BigtableTableAdminClient.parse_crypto_key_version_path + ) instance_path = staticmethod(BigtableTableAdminClient.instance_path) parse_instance_path = staticmethod(BigtableTableAdminClient.parse_instance_path) snapshot_path = staticmethod(BigtableTableAdminClient.snapshot_path) diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py index de3146116..362013ecc 100644 --- a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py +++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py @@ -202,6 +202,32 @@ def parse_cluster_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def crypto_key_version_path( + project: str, + location: str, + key_ring: str, + crypto_key: str, + crypto_key_version: str, + ) -> str: + """Return a fully-qualified crypto_key_version string.""" + return "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}/cryptoKeyVersions/{crypto_key_version}".format( + project=project, + location=location, + key_ring=key_ring, + crypto_key=crypto_key, + crypto_key_version=crypto_key_version, + ) + + @staticmethod + def parse_crypto_key_version_path(path: str) -> Dict[str, str]: + """Parse a crypto_key_version path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/keyRings/(?P.+?)/cryptoKeys/(?P.+?)/cryptoKeyVersions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def instance_path(project: str, instance: str,) -> str: """Return a fully-qualified instance string.""" diff --git a/google/cloud/bigtable_admin_v2/types/__init__.py b/google/cloud/bigtable_admin_v2/types/__init__.py index 26c4b40c9..f637988c4 100644 --- a/google/cloud/bigtable_admin_v2/types/__init__.py +++ b/google/cloud/bigtable_admin_v2/types/__init__.py @@ -53,6 +53,7 @@ Table, ColumnFamily, GcRule, + EncryptionInfo, Snapshot, Backup, BackupInfo, @@ -122,6 +123,7 @@ "Table", "ColumnFamily", "GcRule", + "EncryptionInfo", "Snapshot", "Backup", "BackupInfo", diff --git a/google/cloud/bigtable_admin_v2/types/instance.py b/google/cloud/bigtable_admin_v2/types/instance.py index ddef8a0d1..1f13a0cef 100644 --- a/google/cloud/bigtable_admin_v2/types/instance.py +++ b/google/cloud/bigtable_admin_v2/types/instance.py @@ -110,6 +110,9 @@ class Cluster(proto.Message): (``CreationOnly``) The type of storage used by this cluster to serve its parent instance's tables, unless explicitly overridden. + encryption_config (google.cloud.bigtable_admin_v2.types.Cluster.EncryptionConfig): + Immutable. The encryption configuration for + CMEK-protected clusters. """ class State(proto.Enum): @@ -120,6 +123,28 @@ class State(proto.Enum): RESIZING = 3 DISABLED = 4 + class EncryptionConfig(proto.Message): + r"""Cloud Key Management Service (Cloud KMS) settings for a CMEK- + rotected cluster. + + Attributes: + kms_key_name (str): + Describes the Cloud KMS encryption key that will be used to + protect the destination Bigtable cluster. The requirements + for this key are: + + 1) The Cloud Bigtable service account associated with the + project that contains this cluster must be granted the + ``cloudkms.cryptoKeyEncrypterDecrypter`` role on the CMEK + key. + 2) Only regional keys can be used and the region of the CMEK + key must match the region of the cluster. + 3) All clusters within an instance must use the same CMEK + key. + """ + + kms_key_name = proto.Field(proto.STRING, number=1) + name = proto.Field(proto.STRING, number=1) location = proto.Field(proto.STRING, number=2) @@ -130,6 +155,8 @@ class State(proto.Enum): default_storage_type = proto.Field(proto.ENUM, number=5, enum=common.StorageType,) + encryption_config = proto.Field(proto.MESSAGE, number=6, message=EncryptionConfig,) + class AppProfile(proto.Message): r"""A configuration object describing how Cloud Bigtable should @@ -139,7 +166,7 @@ class AppProfile(proto.Message): name (str): (``OutputOnly``) The unique name of the app profile. Values are of the form - ``projects//instances//appProfiles/[_a-zA-Z0-9][-_.a-zA-Z0-9]*``. + ``projects/{project}/instances/{instance}/appProfiles/[_a-zA-Z0-9][-_.a-zA-Z0-9]*``. etag (str): Strongly validated etag for optimistic concurrency control. Preserve the value returned from ``GetAppProfile`` when diff --git a/google/cloud/bigtable_admin_v2/types/table.py b/google/cloud/bigtable_admin_v2/types/table.py index 96d7750f7..7f5f88e4f 100644 --- a/google/cloud/bigtable_admin_v2/types/table.py +++ b/google/cloud/bigtable_admin_v2/types/table.py @@ -20,6 +20,7 @@ from google.protobuf import duration_pb2 as duration # type: ignore from google.protobuf import timestamp_pb2 as timestamp # type: ignore +from google.rpc import status_pb2 as status # type: ignore __protobuf__ = proto.module( @@ -30,6 +31,7 @@ "Table", "ColumnFamily", "GcRule", + "EncryptionInfo", "Snapshot", "Backup", "BackupInfo", @@ -68,9 +70,8 @@ class Table(proto.Message): Attributes: name (str): - Output only. The unique name of the table. Values are of the - form - ``projects//instances//tables/[_a-zA-Z0-9][-_.a-zA-Z0-9]*``. + The unique name of the table. Values are of the form + ``projects/{project}/instances/{instance}/tables/[_a-zA-Z0-9][-_.a-zA-Z0-9]*``. Views: ``NAME_ONLY``, ``SCHEMA_VIEW``, ``REPLICATION_VIEW``, ``FULL`` cluster_states (Sequence[google.cloud.bigtable_admin_v2.types.Table.ClusterStatesEntry]): @@ -79,7 +80,7 @@ class Table(proto.Message): data in a particular cluster (for example, if its zone is unavailable), then there will be an entry for the cluster with UNKNOWN ``replication_status``. Views: - ``REPLICATION_VIEW``, ``FULL`` + ``REPLICATION_VIEW``, ``ENCRYPTION_VIEW``, ``FULL`` column_families (Sequence[google.cloud.bigtable_admin_v2.types.Table.ColumnFamiliesEntry]): (``CreationOnly``) The column families configured for this table, mapped by column family ID. Views: ``SCHEMA_VIEW``, @@ -110,6 +111,7 @@ class View(proto.Enum): NAME_ONLY = 1 SCHEMA_VIEW = 2 REPLICATION_VIEW = 3 + ENCRYPTION_VIEW = 5 FULL = 4 class ClusterState(proto.Message): @@ -119,6 +121,15 @@ class ClusterState(proto.Message): replication_state (google.cloud.bigtable_admin_v2.types.Table.ClusterState.ReplicationState): Output only. The state of replication for the table in this cluster. + encryption_info (Sequence[google.cloud.bigtable_admin_v2.types.EncryptionInfo]): + Output only. The encryption information for + the table in this cluster. If the encryption key + protecting this resource is customer managed, + then its version can be rotated in Cloud Key + Management Service (Cloud KMS). The primary + version of the key and its status will be + reflected here when changes propagate from Cloud + KMS. """ class ReplicationState(proto.Enum): @@ -134,6 +145,10 @@ class ReplicationState(proto.Enum): proto.ENUM, number=1, enum="Table.ClusterState.ReplicationState", ) + encryption_info = proto.RepeatedField( + proto.MESSAGE, number=2, message="EncryptionInfo", + ) + name = proto.Field(proto.STRING, number=1) cluster_states = proto.MapField( @@ -222,6 +237,40 @@ class Union(proto.Message): union = proto.Field(proto.MESSAGE, number=4, oneof="rule", message=Union,) +class EncryptionInfo(proto.Message): + r"""Encryption information for a given resource. + If this resource is protected with customer managed encryption, + the in-use Cloud Key Management Service (Cloud KMS) key version + is specified along with its status. + + Attributes: + encryption_type (google.cloud.bigtable_admin_v2.types.EncryptionInfo.EncryptionType): + Output only. The type of encryption used to + protect this resource. + encryption_status (google.rpc.status_pb2.Status): + Output only. The status of encrypt/decrypt + calls on underlying data for this resource. + Regardless of status, the existing data is + always encrypted at rest. + kms_key_version (str): + Output only. The version of the Cloud KMS key + specified in the parent cluster that is in use + for the data underlying this table. + """ + + class EncryptionType(proto.Enum): + r"""Possible encryption types for a resource.""" + ENCRYPTION_TYPE_UNSPECIFIED = 0 + GOOGLE_DEFAULT_ENCRYPTION = 1 + CUSTOMER_MANAGED_ENCRYPTION = 2 + + encryption_type = proto.Field(proto.ENUM, number=3, enum=EncryptionType,) + + encryption_status = proto.Field(proto.MESSAGE, number=4, message=status.Status,) + + kms_key_version = proto.Field(proto.STRING, number=2) + + class Snapshot(proto.Message): r"""A snapshot of a table at a particular time. A snapshot can be used as a checkpoint for data restoration or a data source for a @@ -236,7 +285,7 @@ class Snapshot(proto.Message): name (str): Output only. The unique name of the snapshot. Values are of the form - ``projects//instances//clusters//snapshots/``. + ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``. source_table (google.cloud.bigtable_admin_v2.types.Table): Output only. The source table at the time the snapshot was taken. @@ -322,6 +371,9 @@ class Backup(proto.Message): Output only. Size of the backup in bytes. state (google.cloud.bigtable_admin_v2.types.Backup.State): Output only. The current state of the backup. + encryption_info (google.cloud.bigtable_admin_v2.types.EncryptionInfo): + Output only. The encryption information for + the backup. """ class State(proto.Enum): @@ -344,6 +396,8 @@ class State(proto.Enum): state = proto.Field(proto.ENUM, number=7, enum=State,) + encryption_info = proto.Field(proto.MESSAGE, number=9, message="EncryptionInfo",) + class BackupInfo(proto.Message): r"""Information about a backup. diff --git a/scripts/fixup_bigtable_admin_v2_keywords.py b/scripts/fixup_bigtable_admin_v2_keywords.py index d30de39db..3902adff5 100644 --- a/scripts/fixup_bigtable_admin_v2_keywords.py +++ b/scripts/fixup_bigtable_admin_v2_keywords.py @@ -77,7 +77,7 @@ class bigtable_adminCallTransformer(cst.CSTTransformer): 'test_iam_permissions': ('resource', 'permissions', ), 'update_app_profile': ('app_profile', 'update_mask', 'ignore_warnings', ), 'update_backup': ('backup', 'update_mask', ), - 'update_cluster': ('serve_nodes', 'name', 'location', 'state', 'default_storage_type', ), + 'update_cluster': ('serve_nodes', 'name', 'location', 'state', 'default_storage_type', 'encryption_config', ), 'update_instance': ('display_name', 'name', 'state', 'type_', 'labels', ), } diff --git a/synth.metadata b/synth.metadata index 4416e5d4e..fe502187f 100644 --- a/synth.metadata +++ b/synth.metadata @@ -4,15 +4,15 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/python-bigtable.git", - "sha": "6fe87016a159bbdc6bf29856b1cf6e633e16216a" + "sha": "b7489b65319eabd1dbe01d5d01b24500d013b53f" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "8d73f9486fc193a150f6c907dfb9f49431aff3ff", - "internalRef": "332497859" + "sha": "c06bbe28cc7287a55bf7926ee48da2565854de7f", + "internalRef": "359364666" } }, { @@ -51,7 +51,6 @@ } ], "generatedFiles": [ - ".coveragerc", ".flake8", ".github/CONTRIBUTING.md", ".github/ISSUE_TEMPLATE/bug_report.md", @@ -107,46 +106,51 @@ "docs/conf.py", "docs/multiprocessing.rst", "google/cloud/bigtable_admin_v2/__init__.py", - "google/cloud/bigtable_admin_v2/gapic/__init__.py", - "google/cloud/bigtable_admin_v2/gapic/bigtable_instance_admin_client.py", - "google/cloud/bigtable_admin_v2/gapic/bigtable_instance_admin_client_config.py", - "google/cloud/bigtable_admin_v2/gapic/bigtable_table_admin_client.py", - "google/cloud/bigtable_admin_v2/gapic/bigtable_table_admin_client_config.py", - "google/cloud/bigtable_admin_v2/gapic/enums.py", - "google/cloud/bigtable_admin_v2/gapic/transports/__init__.py", - "google/cloud/bigtable_admin_v2/gapic/transports/bigtable_instance_admin_grpc_transport.py", - "google/cloud/bigtable_admin_v2/gapic/transports/bigtable_table_admin_grpc_transport.py", - "google/cloud/bigtable_admin_v2/proto/__init__.py", "google/cloud/bigtable_admin_v2/proto/bigtable_instance_admin.proto", - "google/cloud/bigtable_admin_v2/proto/bigtable_instance_admin_pb2.py", - "google/cloud/bigtable_admin_v2/proto/bigtable_instance_admin_pb2_grpc.py", "google/cloud/bigtable_admin_v2/proto/bigtable_table_admin.proto", - "google/cloud/bigtable_admin_v2/proto/bigtable_table_admin_pb2.py", - "google/cloud/bigtable_admin_v2/proto/bigtable_table_admin_pb2_grpc.py", "google/cloud/bigtable_admin_v2/proto/common.proto", - "google/cloud/bigtable_admin_v2/proto/common_pb2.py", - "google/cloud/bigtable_admin_v2/proto/common_pb2_grpc.py", "google/cloud/bigtable_admin_v2/proto/instance.proto", - "google/cloud/bigtable_admin_v2/proto/instance_pb2.py", - "google/cloud/bigtable_admin_v2/proto/instance_pb2_grpc.py", "google/cloud/bigtable_admin_v2/proto/table.proto", - "google/cloud/bigtable_admin_v2/proto/table_pb2.py", - "google/cloud/bigtable_admin_v2/proto/table_pb2_grpc.py", - "google/cloud/bigtable_admin_v2/types.py", + "google/cloud/bigtable_admin_v2/py.typed", + "google/cloud/bigtable_admin_v2/services/__init__.py", + "google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/__init__.py", + "google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/async_client.py", + "google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py", + "google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/pagers.py", + "google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/__init__.py", + "google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/base.py", + "google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc.py", + "google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc_asyncio.py", + "google/cloud/bigtable_admin_v2/services/bigtable_table_admin/__init__.py", + "google/cloud/bigtable_admin_v2/services/bigtable_table_admin/async_client.py", + "google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py", + "google/cloud/bigtable_admin_v2/services/bigtable_table_admin/pagers.py", + "google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/__init__.py", + "google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/base.py", + "google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc.py", + "google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc_asyncio.py", + "google/cloud/bigtable_admin_v2/types/__init__.py", + "google/cloud/bigtable_admin_v2/types/bigtable_instance_admin.py", + "google/cloud/bigtable_admin_v2/types/bigtable_table_admin.py", + "google/cloud/bigtable_admin_v2/types/common.py", + "google/cloud/bigtable_admin_v2/types/instance.py", + "google/cloud/bigtable_admin_v2/types/table.py", "google/cloud/bigtable_v2/__init__.py", - "google/cloud/bigtable_v2/gapic/__init__.py", - "google/cloud/bigtable_v2/gapic/bigtable_client.py", - "google/cloud/bigtable_v2/gapic/bigtable_client_config.py", - "google/cloud/bigtable_v2/gapic/transports/__init__.py", - "google/cloud/bigtable_v2/gapic/transports/bigtable_grpc_transport.py", - "google/cloud/bigtable_v2/proto/__init__.py", "google/cloud/bigtable_v2/proto/bigtable.proto", - "google/cloud/bigtable_v2/proto/bigtable_pb2.py", - "google/cloud/bigtable_v2/proto/bigtable_pb2_grpc.py", "google/cloud/bigtable_v2/proto/data.proto", - "google/cloud/bigtable_v2/proto/data_pb2.py", - "google/cloud/bigtable_v2/proto/data_pb2_grpc.py", - "google/cloud/bigtable_v2/types.py", + "google/cloud/bigtable_v2/py.typed", + "google/cloud/bigtable_v2/services/__init__.py", + "google/cloud/bigtable_v2/services/bigtable/__init__.py", + "google/cloud/bigtable_v2/services/bigtable/async_client.py", + "google/cloud/bigtable_v2/services/bigtable/client.py", + "google/cloud/bigtable_v2/services/bigtable/transports/__init__.py", + "google/cloud/bigtable_v2/services/bigtable/transports/base.py", + "google/cloud/bigtable_v2/services/bigtable/transports/grpc.py", + "google/cloud/bigtable_v2/services/bigtable/transports/grpc_asyncio.py", + "google/cloud/bigtable_v2/types/__init__.py", + "google/cloud/bigtable_v2/types/bigtable.py", + "google/cloud/bigtable_v2/types/data.py", + "noxfile.py", "renovate.json", "samples/AUTHORING_GUIDE.md", "samples/CONTRIBUTING.md", @@ -160,6 +164,8 @@ "samples/snippets/README.md", "samples/tableadmin/README.md", "scripts/decrypt-secrets.sh", + "scripts/fixup_bigtable_admin_v2_keywords.py", + "scripts/fixup_bigtable_v2_keywords.py", "scripts/readme-gen/readme_gen.py", "scripts/readme-gen/templates/README.tmpl.rst", "scripts/readme-gen/templates/auth.tmpl.rst", @@ -168,8 +174,10 @@ "scripts/readme-gen/templates/install_portaudio.tmpl.rst", "setup.cfg", "testing/.gitignore", - "tests/unit/gapic/v2/test_bigtable_client_v2.py", - "tests/unit/gapic/v2/test_bigtable_instance_admin_client_v2.py", - "tests/unit/gapic/v2/test_bigtable_table_admin_client_v2.py" + "tests/unit/gapic/bigtable_admin_v2/__init__.py", + "tests/unit/gapic/bigtable_admin_v2/test_bigtable_instance_admin.py", + "tests/unit/gapic/bigtable_admin_v2/test_bigtable_table_admin.py", + "tests/unit/gapic/bigtable_v2/__init__.py", + "tests/unit/gapic/bigtable_v2/test_bigtable.py" ] } \ No newline at end of file diff --git a/tests/unit/gapic/bigtable_admin_v2/test_bigtable_instance_admin.py b/tests/unit/gapic/bigtable_admin_v2/test_bigtable_instance_admin.py index 5c6752cac..8a676d825 100644 --- a/tests/unit/gapic/bigtable_admin_v2/test_bigtable_instance_admin.py +++ b/tests/unit/gapic/bigtable_admin_v2/test_bigtable_instance_admin.py @@ -5171,9 +5171,38 @@ def test_parse_cluster_path(): assert expected == actual -def test_instance_path(): +def test_crypto_key_path(): project = "squid" - instance = "clam" + location = "clam" + key_ring = "whelk" + crypto_key = "octopus" + + expected = "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}".format( + project=project, location=location, key_ring=key_ring, crypto_key=crypto_key, + ) + actual = BigtableInstanceAdminClient.crypto_key_path( + project, location, key_ring, crypto_key + ) + assert expected == actual + + +def test_parse_crypto_key_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "key_ring": "cuttlefish", + "crypto_key": "mussel", + } + path = BigtableInstanceAdminClient.crypto_key_path(**expected) + + # Check that the path construction is reversible. + actual = BigtableInstanceAdminClient.parse_crypto_key_path(path) + assert expected == actual + + +def test_instance_path(): + project = "winkle" + instance = "nautilus" expected = "projects/{project}/instances/{instance}".format( project=project, instance=instance, @@ -5184,8 +5213,8 @@ def test_instance_path(): def test_parse_instance_path(): expected = { - "project": "whelk", - "instance": "octopus", + "project": "scallop", + "instance": "abalone", } path = BigtableInstanceAdminClient.instance_path(**expected) @@ -5195,7 +5224,7 @@ def test_parse_instance_path(): def test_common_billing_account_path(): - billing_account = "oyster" + billing_account = "squid" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, @@ -5206,7 +5235,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "nudibranch", + "billing_account": "clam", } path = BigtableInstanceAdminClient.common_billing_account_path(**expected) @@ -5216,7 +5245,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "cuttlefish" + folder = "whelk" expected = "folders/{folder}".format(folder=folder,) actual = BigtableInstanceAdminClient.common_folder_path(folder) @@ -5225,7 +5254,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "mussel", + "folder": "octopus", } path = BigtableInstanceAdminClient.common_folder_path(**expected) @@ -5235,7 +5264,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "winkle" + organization = "oyster" expected = "organizations/{organization}".format(organization=organization,) actual = BigtableInstanceAdminClient.common_organization_path(organization) @@ -5244,7 +5273,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "nautilus", + "organization": "nudibranch", } path = BigtableInstanceAdminClient.common_organization_path(**expected) @@ -5254,7 +5283,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "scallop" + project = "cuttlefish" expected = "projects/{project}".format(project=project,) actual = BigtableInstanceAdminClient.common_project_path(project) @@ -5263,7 +5292,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "abalone", + "project": "mussel", } path = BigtableInstanceAdminClient.common_project_path(**expected) @@ -5273,8 +5302,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "squid" - location = "clam" + project = "winkle" + location = "nautilus" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -5285,8 +5314,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "whelk", - "location": "octopus", + "project": "scallop", + "location": "abalone", } path = BigtableInstanceAdminClient.common_location_path(**expected) diff --git a/tests/unit/gapic/bigtable_admin_v2/test_bigtable_table_admin.py b/tests/unit/gapic/bigtable_admin_v2/test_bigtable_table_admin.py index 92bdb8718..862179e17 100644 --- a/tests/unit/gapic/bigtable_admin_v2/test_bigtable_table_admin.py +++ b/tests/unit/gapic/bigtable_admin_v2/test_bigtable_table_admin.py @@ -51,9 +51,11 @@ from google.iam.v1 import policy_pb2 as policy # type: ignore from google.longrunning import operations_pb2 from google.oauth2 import service_account +from google.protobuf import any_pb2 as gp_any # type: ignore from google.protobuf import duration_pb2 as duration # type: ignore from google.protobuf import field_mask_pb2 as field_mask # type: ignore from google.protobuf import timestamp_pb2 as timestamp # type: ignore +from google.rpc import status_pb2 as status # type: ignore from google.type import expr_pb2 as expr # type: ignore @@ -5868,9 +5870,44 @@ def test_parse_cluster_path(): assert expected == actual -def test_instance_path(): +def test_crypto_key_version_path(): project = "whelk" - instance = "octopus" + location = "octopus" + key_ring = "oyster" + crypto_key = "nudibranch" + crypto_key_version = "cuttlefish" + + expected = "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}/cryptoKeyVersions/{crypto_key_version}".format( + project=project, + location=location, + key_ring=key_ring, + crypto_key=crypto_key, + crypto_key_version=crypto_key_version, + ) + actual = BigtableTableAdminClient.crypto_key_version_path( + project, location, key_ring, crypto_key, crypto_key_version + ) + assert expected == actual + + +def test_parse_crypto_key_version_path(): + expected = { + "project": "mussel", + "location": "winkle", + "key_ring": "nautilus", + "crypto_key": "scallop", + "crypto_key_version": "abalone", + } + path = BigtableTableAdminClient.crypto_key_version_path(**expected) + + # Check that the path construction is reversible. + actual = BigtableTableAdminClient.parse_crypto_key_version_path(path) + assert expected == actual + + +def test_instance_path(): + project = "squid" + instance = "clam" expected = "projects/{project}/instances/{instance}".format( project=project, instance=instance, @@ -5881,8 +5918,8 @@ def test_instance_path(): def test_parse_instance_path(): expected = { - "project": "oyster", - "instance": "nudibranch", + "project": "whelk", + "instance": "octopus", } path = BigtableTableAdminClient.instance_path(**expected) @@ -5892,10 +5929,10 @@ def test_parse_instance_path(): def test_snapshot_path(): - project = "cuttlefish" - instance = "mussel" - cluster = "winkle" - snapshot = "nautilus" + project = "oyster" + instance = "nudibranch" + cluster = "cuttlefish" + snapshot = "mussel" expected = "projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}".format( project=project, instance=instance, cluster=cluster, snapshot=snapshot, @@ -5908,10 +5945,10 @@ def test_snapshot_path(): def test_parse_snapshot_path(): expected = { - "project": "scallop", - "instance": "abalone", - "cluster": "squid", - "snapshot": "clam", + "project": "winkle", + "instance": "nautilus", + "cluster": "scallop", + "snapshot": "abalone", } path = BigtableTableAdminClient.snapshot_path(**expected) @@ -5921,9 +5958,9 @@ def test_parse_snapshot_path(): def test_table_path(): - project = "whelk" - instance = "octopus" - table = "oyster" + project = "squid" + instance = "clam" + table = "whelk" expected = "projects/{project}/instances/{instance}/tables/{table}".format( project=project, instance=instance, table=table, @@ -5934,9 +5971,9 @@ def test_table_path(): def test_parse_table_path(): expected = { - "project": "nudibranch", - "instance": "cuttlefish", - "table": "mussel", + "project": "octopus", + "instance": "oyster", + "table": "nudibranch", } path = BigtableTableAdminClient.table_path(**expected) @@ -5946,7 +5983,7 @@ def test_parse_table_path(): def test_common_billing_account_path(): - billing_account = "winkle" + billing_account = "cuttlefish" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, @@ -5957,7 +5994,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "nautilus", + "billing_account": "mussel", } path = BigtableTableAdminClient.common_billing_account_path(**expected) @@ -5967,7 +6004,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "scallop" + folder = "winkle" expected = "folders/{folder}".format(folder=folder,) actual = BigtableTableAdminClient.common_folder_path(folder) @@ -5976,7 +6013,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "abalone", + "folder": "nautilus", } path = BigtableTableAdminClient.common_folder_path(**expected) @@ -5986,7 +6023,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "squid" + organization = "scallop" expected = "organizations/{organization}".format(organization=organization,) actual = BigtableTableAdminClient.common_organization_path(organization) @@ -5995,7 +6032,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "clam", + "organization": "abalone", } path = BigtableTableAdminClient.common_organization_path(**expected) @@ -6005,7 +6042,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "whelk" + project = "squid" expected = "projects/{project}".format(project=project,) actual = BigtableTableAdminClient.common_project_path(project) @@ -6014,7 +6051,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "octopus", + "project": "clam", } path = BigtableTableAdminClient.common_project_path(**expected) @@ -6024,8 +6061,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "oyster" - location = "nudibranch" + project = "whelk" + location = "octopus" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -6036,8 +6073,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "cuttlefish", - "location": "mussel", + "project": "oyster", + "location": "nudibranch", } path = BigtableTableAdminClient.common_location_path(**expected)