Skip to content

Commit 4282340

Browse files
authored
feat: add samples for CMMR phase 2 (#672)
* feat(spanner): add support for CMMR phase 2 * fix lint issues * re-trigger build
1 parent 75f7198 commit 4282340

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

samples/samples/snippets.py

+92
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
import time
3030

3131
from google.cloud import spanner
32+
from google.cloud.spanner_admin_instance_v1.types import spanner_instance_admin
3233
from google.cloud.spanner_v1 import param_types
34+
from google.protobuf import field_mask_pb2 # type: ignore
3335

3436
OPERATION_TIMEOUT_SECONDS = 240
3537

@@ -2116,6 +2118,96 @@ def set_request_tag(instance_id, database_id):
21162118
# [END spanner_set_request_tag]
21172119

21182120

2121+
# [START spanner_create_instance_config]
2122+
def create_instance_config(user_config_name, base_config_id):
2123+
"""Creates the new user-managed instance configuration using base instance config."""
2124+
2125+
# user_config_name = `custom-nam11`
2126+
# base_config_id = `projects/<project>/instanceConfigs/nam11`
2127+
spanner_client = spanner.Client()
2128+
base_config = spanner_client.instance_admin_api.get_instance_config(
2129+
name=base_config_id)
2130+
2131+
# The replicas for the custom instance configuration must include all the replicas of the base
2132+
# configuration, in addition to at least one from the list of optional replicas of the base
2133+
# configuration.
2134+
replicas = []
2135+
for replica in base_config.replicas:
2136+
replicas.append(replica)
2137+
replicas.append(base_config.optional_replicas[0])
2138+
operation = spanner_client.instance_admin_api.create_instance_config(
2139+
parent=spanner_client.project_name,
2140+
instance_config_id=user_config_name,
2141+
instance_config=spanner_instance_admin.InstanceConfig(
2142+
name="{}/instanceConfigs/{}".format(spanner_client.project_name, user_config_name),
2143+
display_name="custom-python-samples",
2144+
config_type=spanner_instance_admin.InstanceConfig.Type.USER_MANAGED,
2145+
replicas=replicas,
2146+
base_config=base_config.name,
2147+
labels={
2148+
"python_cloud_spanner_samples": "true"
2149+
}
2150+
))
2151+
print("Waiting for operation to complete...")
2152+
operation.result(OPERATION_TIMEOUT_SECONDS)
2153+
2154+
print("Created instance configuration {}".format(user_config_name))
2155+
2156+
2157+
# [END spanner_create_instance_config]
2158+
2159+
# [START spanner_update_instance_config]
2160+
def update_instance_config(user_config_name):
2161+
"""Updates the user-managed instance configuration."""
2162+
2163+
# user_config_name = `custom-nam11`
2164+
spanner_client = spanner.Client()
2165+
config = spanner_client.instance_admin_api.get_instance_config(
2166+
name="{}/instanceConfigs/{}".format(spanner_client.project_name, user_config_name))
2167+
config.display_name = "updated custom instance config"
2168+
config.labels["updated"] = "true"
2169+
operation = spanner_client.instance_admin_api.update_instance_config(instance_config=config,
2170+
update_mask=field_mask_pb2.FieldMask(
2171+
paths=["display_name", "labels"]))
2172+
print("Waiting for operation to complete...")
2173+
operation.result(OPERATION_TIMEOUT_SECONDS)
2174+
print("Updated instance configuration {}".format(user_config_name))
2175+
2176+
2177+
# [END spanner_update_instance_config]
2178+
2179+
# [START spanner_delete_instance_config]
2180+
def delete_instance_config(user_config_id):
2181+
"""Deleted the user-managed instance configuration."""
2182+
spanner_client = spanner.Client()
2183+
spanner_client.instance_admin_api.delete_instance_config(
2184+
name=user_config_id)
2185+
print("Instance config {} successfully deleted".format(user_config_id))
2186+
2187+
2188+
# [END spanner_delete_instance_config]
2189+
2190+
2191+
# [START spanner_list_instance_config_operations]
2192+
def list_instance_config_operations():
2193+
"""List the user-managed instance configuration operations."""
2194+
spanner_client = spanner.Client()
2195+
operations = spanner_client.instance_admin_api.list_instance_config_operations(
2196+
request=spanner_instance_admin.ListInstanceConfigOperationsRequest(parent=spanner_client.project_name,
2197+
filter="(metadata.@type=type.googleapis.com/google.spanner.admin.instance.v1.CreateInstanceConfigMetadata)"))
2198+
for op in operations:
2199+
metadata = spanner_instance_admin.CreateInstanceConfigMetadata.pb(spanner_instance_admin.CreateInstanceConfigMetadata())
2200+
op.metadata.Unpack(metadata)
2201+
print(
2202+
"List instance config operations {} is {}% completed.".format(
2203+
metadata.instance_config.name, metadata.progress.progress_percent
2204+
)
2205+
)
2206+
2207+
2208+
# [END spanner_list_instance_config_operations]
2209+
2210+
21192211
if __name__ == "__main__": # noqa: C901
21202212
parser = argparse.ArgumentParser(
21212213
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter

samples/samples/snippets_test.py

+43
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,20 @@ def default_leader():
9595
return "us-east4"
9696

9797

98+
@pytest.fixture(scope="module")
99+
def user_managed_instance_config_name(spanner_client):
100+
name = f"custom-python-samples-config-{uuid.uuid4().hex[:10]}"
101+
yield name
102+
snippets.delete_instance_config("{}/instanceConfigs/{}".format(
103+
spanner_client.project_name, name))
104+
return
105+
106+
107+
@pytest.fixture(scope="module")
108+
def base_instance_config_id(spanner_client):
109+
return "{}/instanceConfigs/{}".format(spanner_client.project_name, "nam7")
110+
111+
98112
def test_create_instance_explicit(spanner_client, create_instance_id):
99113
# Rather than re-use 'sample_isntance', we create a new instance, to
100114
# ensure that the 'create_instance' snippet is tested.
@@ -148,6 +162,35 @@ def test_list_instance_config(capsys):
148162
assert "regional-us-central1" in out
149163

150164

165+
@pytest.mark.dependency(name="create_instance_config")
166+
def test_create_instance_config(capsys, user_managed_instance_config_name, base_instance_config_id):
167+
snippets.create_instance_config(user_managed_instance_config_name, base_instance_config_id)
168+
out, _ = capsys.readouterr()
169+
assert "Created instance configuration" in out
170+
171+
172+
@pytest.mark.dependency(depends=["create_instance_config"])
173+
def test_update_instance_config(capsys, user_managed_instance_config_name):
174+
snippets.update_instance_config(user_managed_instance_config_name)
175+
out, _ = capsys.readouterr()
176+
assert "Updated instance configuration" in out
177+
178+
179+
@pytest.mark.dependency(depends=["create_instance_config"])
180+
def test_delete_instance_config(capsys, user_managed_instance_config_name):
181+
spanner_client = spanner.Client()
182+
snippets.delete_instance_config("{}/instanceConfigs/{}".format(
183+
spanner_client.project_name, user_managed_instance_config_name))
184+
out, _ = capsys.readouterr()
185+
assert "successfully deleted" in out
186+
187+
188+
def test_list_instance_config_operations(capsys):
189+
snippets.list_instance_config_operations()
190+
out, _ = capsys.readouterr()
191+
assert "List instance config operations" in out
192+
193+
151194
def test_list_databases(capsys, instance_id):
152195
snippets.list_databases(instance_id)
153196
out, _ = capsys.readouterr()

0 commit comments

Comments
 (0)