Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: samples and tests for admin database APIs #1099

Merged
merged 13 commits into from
Feb 26, 2024
Prev Previous commit
Next Next commit
incorporate suggestions
  • Loading branch information
rahul2393 committed Feb 22, 2024
commit 4f6eccec2948eb368af43c839efa09fc8858db7f
100 changes: 98 additions & 2 deletions samples/samples/admin/samples.py
Expand Up @@ -22,6 +22,10 @@
import time

from google.cloud import spanner
from google.type import expr_pb2
from google.iam.v1 import iam_policy_pb2
from google.iam.v1 import options_pb2
from google.iam.v1 import policy_pb2
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
from google.cloud.spanner_admin_instance_v1.types import spanner_instance_admin

Expand All @@ -38,7 +42,7 @@ def create_instance(instance_id):
)

operation = spanner_client.instance_admin_api.create_instance(
parent="projects/{}".format(spanner_client.project),
parent="projects/{}".format(spanner_client.project_name),
instance_id=instance_id,
instance=spanner_instance_admin.Instance(
config=config_name,
Expand Down Expand Up @@ -71,7 +75,7 @@ def create_instance_with_processing_units(instance_id, processing_units):
)

request = spanner_instance_admin.CreateInstanceRequest(
parent="projects/{}".format(spanner_client.project),
parent="projects/{}".format(spanner_client.project_name),
instance_id=instance_id,
instance=spanner_instance_admin.Instance(
config=config_name,
harshachinta marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -365,6 +369,44 @@ def add_numeric_column(instance_id, database_id):
# [END spanner_add_numeric_column]


# [START spanner_create_table_with_timestamp_column]
def create_table_with_timestamp(instance_id, database_id):
"""Creates a table with a COMMIT_TIMESTAMP column."""

spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)

request = spanner_database_admin.UpdateDatabaseDdlRequest(
database=database.name,
statements=[
"""CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate Date,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL
OPTIONS(allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE"""
],
)

operation = spanner_client.database_admin_api.update_database_ddl(request)

print("Waiting for operation to complete...")
operation.result(OPERATION_TIMEOUT_SECONDS)

print(
"Created Performances table on database {} on instance {}".format(
database_id, instance_id
)
)


# [END spanner_create_table_with_timestamp_column]


# [START spanner_create_table_with_foreign_key_delete_cascade]
def create_table_with_foreign_key_delete_cascade(instance_id, database_id):
"""Creates a table with foreign key delete cascade action"""
Expand Down Expand Up @@ -703,3 +745,57 @@ def add_storing_index(instance_id, database_id):


# [END spanner_create_storing_index]


def enable_fine_grained_access(
instance_id,
database_id,
iam_member="user:[email protected]",
database_role="new_parent",
title="condition title",
):
"""Showcases how to enable fine grained access control."""
# [START spanner_enable_fine_grained_access]
# instance_id = "your-spanner-instance"
# database_id = "your-spanner-db-id"
# iam_member = "user:[email protected]"
# database_role = "new_parent"
# title = "condition title"
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)

# The policy in the response from getDatabaseIAMPolicy might use the policy version
# that you specified, or it might use a lower policy version. For example, if you
# specify version 3, but the policy has no conditional role bindings, the response
# uses version 1. Valid values are 0, 1, and 3.
request = iam_policy_pb2.GetIamPolicyRequest(
resource=database.name,
options=options_pb2.GetPolicyOptions(requested_policy_version=3),
)
policy = spanner_client.database_admin_api.get_iam_policy(request=request)
if policy.version < 3:
policy.version = 3

new_binding = policy_pb2.Binding(
role="roles/spanner.fineGrainedAccessUser",
members=[iam_member],
condition=expr_pb2.Expr(
title=title,
expression=f'resource.name.endsWith("/databaseRoles/{database_role}")',
),
)

policy.version = 3
policy.bindings.append(new_binding)
set_request = iam_policy_pb2.SetIamPolicyRequest(
resource=database.name,
policy=policy,
)
spanner_client.database_admin_api.set_iam_policy(set_request)

new_policy = spanner_client.database_admin_api.get_iam_policy(request=request)
print(
f"Enabled fine-grained access in IAM. New policy has version {new_policy.version}"
)
# [END spanner_enable_fine_grained_access]
12 changes: 11 additions & 1 deletion samples/samples/admin/samples_test.py
Expand Up @@ -177,7 +177,9 @@ def test_create_database_with_default_leader(
assert default_leader in out


@pytest.mark.dependency(name="add_and_drop_database_roles")
@pytest.mark.dependency(
name="add_and_drop_database_roles", depends=["create_table_with_datatypes"]
)
def test_add_and_drop_database_roles(capsys, instance_id, sample_database):
samples.add_and_drop_database_roles(instance_id, sample_database.database_id)
out, _ = capsys.readouterr()
Expand All @@ -192,6 +194,13 @@ def test_create_table_with_datatypes(capsys, instance_id, sample_database):
assert "Created Venues table on database" in out


@pytest.mark.dependency(name="create_table_with_timestamp")
def test_create_table_with_timestamp(capsys, instance_id, sample_database):
samples.create_table_with_timestamp(instance_id, sample_database.database_id)
out, _ = capsys.readouterr()
assert "Created Performances table on database" in out


@pytest.mark.dependency(
name="add_json_column",
depends=["create_table_with_datatypes"],
Expand Down Expand Up @@ -251,6 +260,7 @@ def test_drop_foreign_key_contraint_delete_cascade(
assert "Altered ShoppingCarts table to drop FKShoppingCartsCustomerName" in out


@pytest.mark.dependency(name="create_sequence")
def test_create_sequence(capsys, instance_id, bit_reverse_sequence_database):
samples.create_sequence(instance_id, bit_reverse_sequence_database.database_id)
out, _ = capsys.readouterr()
Expand Down