Skip to content

Commit 479e6cb

Browse files
committed
Implementing Cluster.create().
1 parent 13f8693 commit 479e6cb

2 files changed

Lines changed: 134 additions & 1 deletion

File tree

gcloud/bigtable/cluster.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import re
1919

20+
from gcloud.bigtable._generated import bigtable_cluster_data_pb2 as data_pb2
2021
from gcloud.bigtable._generated import (
2122
bigtable_cluster_service_messages_pb2 as messages_pb2)
2223
from gcloud.bigtable.table import Table
@@ -52,6 +53,27 @@ def _get_pb_property_value(message_pb, property_name):
5253
return getattr(message_pb, property_name)
5354

5455

56+
def _prepare_create_request(cluster):
57+
"""Creates a protobuf request for a CreateCluster request.
58+
59+
:type cluster: :class:`Cluster`
60+
:param cluster: The cluster to be created.
61+
62+
:rtype: :class:`.messages_pb2.CreateClusterRequest`
63+
:returns: The CreateCluster request object containing the cluster info.
64+
"""
65+
zone_full_name = ('projects/' + cluster._client.project +
66+
'/zones/' + cluster.zone)
67+
return messages_pb2.CreateClusterRequest(
68+
name=zone_full_name,
69+
cluster_id=cluster.cluster_id,
70+
cluster=data_pb2.Cluster(
71+
display_name=cluster.display_name,
72+
serve_nodes=cluster.serve_nodes,
73+
),
74+
)
75+
76+
5577
class Cluster(object):
5678
"""Representation of a Google Cloud Bigtable Cluster.
5779
@@ -83,6 +105,7 @@ def __init__(self, zone, cluster_id, client,
83105
self.display_name = display_name or cluster_id
84106
self.serve_nodes = serve_nodes
85107
self._client = client
108+
self._operation = None
86109

87110
def table(self, table_id):
88111
"""Factory to create a table associated with this cluster.
@@ -171,3 +194,27 @@ def reload(self):
171194
# NOTE: _update_from_pb does not check that the project, zone and
172195
# cluster ID on the response match the request.
173196
self._update_from_pb(cluster_pb)
197+
198+
def create(self):
199+
"""Create this cluster.
200+
201+
.. note::
202+
203+
Uses the ``project``, ``zone`` and ``cluster_id`` on the current
204+
:class:`Cluster` in addition to the ``display_name`` and
205+
``serve_nodes``. If you'd like to change them before creating,
206+
reset the values via
207+
208+
.. code:: python
209+
210+
cluster.display_name = 'New display name'
211+
cluster.cluster_id = 'i-changed-my-mind'
212+
213+
before calling :meth:`create`.
214+
"""
215+
request_pb = _prepare_create_request(self)
216+
# We expect an `operations_pb2.Operation`.
217+
cluster_pb = self._client._cluster_stub.CreateCluster(
218+
request_pb, self._client.timeout_seconds)
219+
220+
self._operation = cluster_pb.current_operation

gcloud/bigtable/test_cluster.py

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ def test_reload(self):
171171
zone = 'zone'
172172
cluster_id = 'cluster-id'
173173
timeout_seconds = 123
174-
client = _Client(project=project, timeout_seconds=timeout_seconds)
174+
175+
client = _Client(project, timeout_seconds=timeout_seconds)
175176
cluster = self._makeOne(zone, cluster_id, client)
176177

177178
# Create request_pb
@@ -210,6 +211,58 @@ def test_reload(self):
210211
self.assertEqual(cluster.serve_nodes, serve_nodes)
211212
self.assertEqual(cluster.display_name, display_name)
212213

214+
def test_create(self):
215+
from gcloud._testing import _Monkey
216+
from gcloud.bigtable._generated import (
217+
bigtable_cluster_data_pb2 as data_pb2)
218+
from gcloud.bigtable._generated import operations_pb2
219+
from gcloud.bigtable._testing import _FakeStub
220+
from gcloud.bigtable import cluster as MUT
221+
222+
project = 'PROJECT'
223+
zone = 'zone'
224+
cluster_id = 'cluster-id'
225+
timeout_seconds = 578
226+
227+
client = _Client(project, timeout_seconds=timeout_seconds)
228+
cluster = self._makeOne(zone, cluster_id, client)
229+
230+
# Create request_pb. Just a mock since we monkey patch
231+
# _prepare_create_request
232+
request_pb = object()
233+
234+
# Create response_pb
235+
op_id = 5678
236+
op_name = ('operations/projects/%s/zones/%s/clusters/%s/'
237+
'operations/%d' % (project, zone, cluster_id, op_id))
238+
current_op = operations_pb2.Operation(name=op_name)
239+
response_pb = data_pb2.Cluster(current_operation=current_op)
240+
241+
# Patch the stub used by the API method.
242+
client._cluster_stub = stub = _FakeStub(response_pb)
243+
244+
# Create expected_result.
245+
expected_result = None # create() has no return value.
246+
247+
# Perform the method and check the result.
248+
prep_create_called = []
249+
250+
def mock_prep_create_req(cluster):
251+
prep_create_called.append(cluster)
252+
return request_pb
253+
254+
with _Monkey(MUT, _prepare_create_request=mock_prep_create_req):
255+
result = cluster.create()
256+
257+
self.assertEqual(result, expected_result)
258+
self.assertEqual(stub.method_calls, [(
259+
'CreateCluster',
260+
(request_pb, timeout_seconds),
261+
{},
262+
)])
263+
self.assertEqual(cluster._operation, current_op)
264+
self.assertEqual(prep_create_called, [cluster])
265+
213266

214267
class Test__get_pb_property_value(unittest2.TestCase):
215268

@@ -233,6 +286,39 @@ def test_with_value_unset_on_pb(self):
233286
self._callFUT(cluster_pb, 'serve_nodes')
234287

235288

289+
class Test__prepare_create_request(unittest2.TestCase):
290+
291+
def _callFUT(self, cluster):
292+
from gcloud.bigtable.cluster import _prepare_create_request
293+
return _prepare_create_request(cluster)
294+
295+
def test_it(self):
296+
from gcloud.bigtable._generated import (
297+
bigtable_cluster_data_pb2 as data_pb2)
298+
from gcloud.bigtable._generated import (
299+
bigtable_cluster_service_messages_pb2 as messages_pb2)
300+
from gcloud.bigtable.cluster import Cluster
301+
302+
project = 'PROJECT'
303+
zone = 'zone'
304+
cluster_id = 'cluster-id'
305+
display_name = u'DISPLAY_NAME'
306+
serve_nodes = 8
307+
client = _Client(project)
308+
309+
cluster = Cluster(zone, cluster_id, client,
310+
display_name=display_name, serve_nodes=serve_nodes)
311+
request_pb = self._callFUT(cluster)
312+
self.assertTrue(isinstance(request_pb,
313+
messages_pb2.CreateClusterRequest))
314+
self.assertEqual(request_pb.cluster_id, cluster_id)
315+
self.assertEqual(request_pb.name,
316+
'projects/' + project + '/zones/' + zone)
317+
self.assertTrue(isinstance(request_pb.cluster, data_pb2.Cluster))
318+
self.assertEqual(request_pb.cluster.display_name, display_name)
319+
self.assertEqual(request_pb.cluster.serve_nodes, serve_nodes)
320+
321+
236322
class _Client(object):
237323

238324
def __init__(self, project, timeout_seconds=None):

0 commit comments

Comments
 (0)