2727from gcloud .bigtable ._generated_v2 import (
2828 bigtable_table_admin_pb2 as table_messages_v2_pb2 )
2929from gcloud .bigtable .cluster import Cluster
30+ from gcloud .bigtable .cluster import DEFAULT_SERVE_NODES
3031from gcloud .bigtable .table import Table
3132
3233
34+ _EXISTING_INSTANCE_LOCATION_ID = 'see-existing-cluster'
3335_INSTANCE_NAME_RE = re .compile (r'^projects/(?P<project>[^/]+)/'
3436 r'instances/(?P<instance_id>[a-z][-a-z0-9]*)$' )
3537_OPERATION_NAME_RE = re .compile (r'^operations/projects/([^/]+)/'
36- r'instances/([a-z][-a-z0-9]*)/operations/'
37- r'(?P<operation_id>\d+)$' )
38+ r'instances/([a-z][-a-z0-9]*)/'
39+ r'locations/(?P<location_id>[a-z][-a-z0-9]*)/'
40+ r'operations/(?P<operation_id>\d+)$' )
3841_TYPE_URL_BASE = 'type.googleapis.com/google.bigtable.'
3942_ADMIN_TYPE_URL_BASE = _TYPE_URL_BASE + 'admin.v2.'
4043_INSTANCE_CREATE_METADATA = _ADMIN_TYPE_URL_BASE + 'CreateInstanceMetadata'
@@ -53,13 +56,19 @@ def _prepare_create_request(instance):
5356 :returns: The CreateInstance request object containing the instance info.
5457 """
5558 parent_name = ('projects/' + instance ._client .project )
56- return messages_v2_pb2 .CreateInstanceRequest (
59+ message = messages_v2_pb2 .CreateInstanceRequest (
5760 parent = parent_name ,
5861 instance_id = instance .instance_id ,
5962 instance = data_v2_pb2 .Instance (
6063 display_name = instance .display_name ,
6164 ),
6265 )
66+ cluster = message .clusters [instance .instance_id ]
67+ cluster .name = instance .name + '/clusters/' + instance .instance_id
68+ cluster .location = (
69+ parent_name + '/locations/' + instance ._cluster_location_id )
70+ cluster .serve_nodes = instance ._cluster_serve_nodes
71+ return message
6372
6473
6574def _parse_pb_any_to_native (any_val , expected_type = None ):
@@ -91,25 +100,24 @@ def _process_operation(operation_pb):
91100 :param operation_pb: The long-running operation response from a
92101 Create/Update/Undelete instance request.
93102
94- :rtype: tuple
95- :returns: A pair of an integer and datetime stamp. The integer is the ID
96- of the operation (``operation_id``) and the timestamp when
97- the create operation began (``operation_begin``).
103+ :rtype: (int, str, datetime)
104+ :returns: (operation_id, location_id, operation_begin).
98105 :raises: :class:`ValueError <exceptions.ValueError>` if the operation name
99106 doesn't match the :data:`_OPERATION_NAME_RE` regex.
100107 """
101108 match = _OPERATION_NAME_RE .match (operation_pb .name )
102109 if match is None :
103110 raise ValueError ('Operation name was not in the expected '
104- 'format after a instance modification .' ,
111+ 'format after instance creation .' ,
105112 operation_pb .name )
113+ location_id = match .group ('location_id' )
106114 operation_id = int (match .group ('operation_id' ))
107115
108116 request_metadata = _parse_pb_any_to_native (operation_pb .metadata )
109117 operation_begin = _pb_timestamp_to_datetime (
110118 request_metadata .request_time )
111119
112- return operation_id , operation_begin
120+ return operation_id , location_id , operation_begin
113121
114122
115123class Operation (object ):
@@ -128,14 +136,18 @@ class Operation(object):
128136 :type begin: :class:`datetime.datetime`
129137 :param begin: The time when the operation was started.
130138
139+ :type location_id: str
140+ :param location_id: ID of the location in which the operation is running
141+
131142 :type instance: :class:`Instance`
132143 :param instance: The instance that created the operation.
133144 """
134145
135- def __init__ (self , op_type , op_id , begin , instance = None ):
146+ def __init__ (self , op_type , op_id , begin , location_id , instance = None ):
136147 self .op_type = op_type
137148 self .op_id = op_id
138149 self .begin = begin
150+ self .location_id = location_id
139151 self ._instance = instance
140152 self ._complete = False
141153
@@ -145,6 +157,7 @@ def __eq__(self, other):
145157 return (other .op_type == self .op_type and
146158 other .op_id == self .op_id and
147159 other .begin == self .begin and
160+ other .location_id == self .location_id and
148161 other ._instance == self ._instance and
149162 other ._complete == self ._complete )
150163
@@ -162,8 +175,9 @@ def finished(self):
162175 if self ._complete :
163176 raise ValueError ('The operation has completed.' )
164177
165- operation_name = ('operations/' + self ._instance .name +
166- '/operations/%d' % (self .op_id ,))
178+ operation_name = (
179+ 'operations/%s/locations/%s/operations/%d' %
180+ (self ._instance .name , self .location_id , self .op_id ))
167181 request_pb = operations_pb2 .GetOperationRequest (name = operation_name )
168182 # We expect a `google.longrunning.operations_pb2.Operation`.
169183 operation_pb = self ._instance ._client ._operations_stub .GetOperation (
@@ -199,17 +213,30 @@ class Instance(object):
199213 :param client: The client that owns the instance. Provides
200214 authorization and a project ID.
201215
216+ :type location_id: str
217+ :param location_id: ID of the location in which the instance will be
218+ created. Required for instances which do not yet
219+ exist.
220+
202221 :type display_name: str
203222 :param display_name: (Optional) The display name for the instance in the
204223 Cloud Console UI. (Must be between 4 and 30
205224 characters.) If this value is not set in the
206225 constructor, will fall back to the instance ID.
226+
227+ :type serve_nodes: int
228+ :param serve_nodes: (Optional) The number of nodes in the instance's
229+ cluster; used to set up the instance's cluster.
207230 """
208231
209232 def __init__ (self , instance_id , client ,
210- display_name = None ):
233+ location_id = _EXISTING_INSTANCE_LOCATION_ID ,
234+ display_name = None ,
235+ serve_nodes = DEFAULT_SERVE_NODES ):
211236 self .instance_id = instance_id
212237 self .display_name = display_name or instance_id
238+ self ._cluster_location_id = location_id
239+ self ._cluster_serve_nodes = serve_nodes
213240 self ._client = client
214241
215242 def _update_from_pb (self , instance_pb ):
@@ -246,8 +273,9 @@ def from_pb(cls, instance_pb, client):
246273 if match .group ('project' ) != client .project :
247274 raise ValueError ('Project ID on instance does not match the '
248275 'project ID on the client' )
276+ instance_id = match .group ('instance_id' )
249277
250- result = cls (match . group ( ' instance_id' ) , client )
278+ result = cls (instance_id , client , _EXISTING_INSTANCE_LOCATION_ID )
251279 result ._update_from_pb (instance_pb )
252280 return result
253281
@@ -262,6 +290,7 @@ def copy(self):
262290 """
263291 new_client = self ._client .copy ()
264292 return self .__class__ (self .instance_id , new_client ,
293+ self ._cluster_location_id ,
265294 display_name = self .display_name )
266295
267296 @property
@@ -332,8 +361,8 @@ def create(self):
332361 operation_pb = self ._client ._instance_stub .CreateInstance (
333362 request_pb , self ._client .timeout_seconds )
334363
335- op_id , op_begin = _process_operation (operation_pb )
336- return Operation ('create' , op_id , op_begin , instance = self )
364+ op_id , loc_id , op_begin = _process_operation (operation_pb )
365+ return Operation ('create' , op_id , op_begin , loc_id , instance = self )
337366
338367 def update (self ):
339368 """Update this instance.
0 commit comments