gcloud 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +2 -3
- data/CHANGELOG +4 -0
- data/LICENSE +674 -0
- data/Manifest +111 -0
- data/README.md +4 -3
- data/bin/gcutil +53 -0
- data/gcloud.gemspec +4 -3
- data/packages/gcutil-1.7.1/CHANGELOG +197 -0
- data/packages/gcutil-1.7.1/LICENSE +202 -0
- data/packages/gcutil-1.7.1/VERSION +1 -0
- data/packages/gcutil-1.7.1/gcutil +53 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/LICENSE +23 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/__init__.py +1 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/discovery.py +743 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/errors.py +123 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/ext/__init__.py +0 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/http.py +1443 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/mimeparse.py +172 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/model.py +385 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/schema.py +303 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/__init__.py +1 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/anyjson.py +32 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/appengine.py +528 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/client.py +1139 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/clientsecrets.py +105 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/crypt.py +244 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/django_orm.py +124 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/file.py +107 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/locked_file.py +343 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/multistore_file.py +379 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/tools.py +174 -0
- data/packages/gcutil-1.7.1/lib/google_api_python_client/uritemplate/__init__.py +147 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/LICENSE +202 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/__init__.py +3 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/__init__.py +3 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/app.py +356 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.py +783 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/basetest.py +1260 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/datelib.py +421 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/debug.py +60 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/file_util.py +181 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/resources.py +67 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/run_script_module.py +217 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/setup_command.py +159 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/shellutil.py +49 -0
- data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/stopwatch.py +204 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/__init__.py +0 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auth_helper.py +140 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auth_helper_test.py +149 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auto_auth.py +130 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auto_auth_test.py +75 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/basic_cmds.py +128 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/basic_cmds_test.py +111 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/command_base.py +1808 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/command_base_test.py +1651 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/compute/v1beta13.json +2851 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/compute/v1beta14.json +3361 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/disk_cmds.py +342 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/disk_cmds_test.py +474 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/firewall_cmds.py +344 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/firewall_cmds_test.py +231 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/flags_cache.py +274 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/gcutil +89 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/gcutil_logging.py +69 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/image_cmds.py +262 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/image_cmds_test.py +172 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/instance_cmds.py +1506 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/instance_cmds_test.py +1904 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/kernel_cmds.py +91 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/kernel_cmds_test.py +56 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/machine_type_cmds.py +106 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/machine_type_cmds_test.py +59 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata.py +96 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata_lib.py +357 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata_test.py +84 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/mock_api.py +420 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/mock_metadata.py +58 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/move_cmds.py +824 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/move_cmds_test.py +307 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/network_cmds.py +178 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/network_cmds_test.py +133 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/operation_cmds.py +181 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/operation_cmds_test.py +196 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/path_initializer.py +38 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/project_cmds.py +173 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/project_cmds_test.py +111 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/scopes.py +61 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/scopes_test.py +50 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/snapshot_cmds.py +276 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/snapshot_cmds_test.py +260 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/ssh_keys.py +266 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/ssh_keys_test.py +128 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/table_formatter.py +563 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/thread_pool.py +188 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/thread_pool_test.py +88 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/utils.py +208 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/utils_test.py +193 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version.py +17 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version_checker.py +246 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version_checker_test.py +271 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/zone_cmds.py +151 -0
- data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/zone_cmds_test.py +60 -0
- data/packages/gcutil-1.7.1/lib/httplib2/LICENSE +21 -0
- data/packages/gcutil-1.7.1/lib/httplib2/httplib2/__init__.py +1630 -0
- data/packages/gcutil-1.7.1/lib/httplib2/httplib2/cacerts.txt +714 -0
- data/packages/gcutil-1.7.1/lib/httplib2/httplib2/iri2uri.py +110 -0
- data/packages/gcutil-1.7.1/lib/httplib2/httplib2/socks.py +438 -0
- data/packages/gcutil-1.7.1/lib/iso8601/LICENSE +20 -0
- data/packages/gcutil-1.7.1/lib/iso8601/iso8601/__init__.py +1 -0
- data/packages/gcutil-1.7.1/lib/iso8601/iso8601/iso8601.py +102 -0
- data/packages/gcutil-1.7.1/lib/iso8601/iso8601/test_iso8601.py +111 -0
- data/packages/gcutil-1.7.1/lib/python_gflags/AUTHORS +2 -0
- data/packages/gcutil-1.7.1/lib/python_gflags/LICENSE +28 -0
- data/packages/gcutil-1.7.1/lib/python_gflags/gflags.py +2862 -0
- data/packages/gcutil-1.7.1/lib/python_gflags/gflags2man.py +544 -0
- data/packages/gcutil-1.7.1/lib/python_gflags/gflags_validators.py +187 -0
- metadata +118 -5
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# Copyright 2012 Google Inc. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Commands for interacting with Google Compute Engine persistent disks."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
import time
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
from google.apputils import app
|
|
23
|
+
from google.apputils import appcommands
|
|
24
|
+
import gflags as flags
|
|
25
|
+
|
|
26
|
+
from gcutil import command_base
|
|
27
|
+
from gcutil import gcutil_logging
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
FLAGS = flags.FLAGS
|
|
31
|
+
LOGGER = gcutil_logging.LOGGER
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class DiskCommand(command_base.GoogleComputeCommand):
|
|
35
|
+
"""Base command for working with the disks collection."""
|
|
36
|
+
|
|
37
|
+
default_sort_field = 'name'
|
|
38
|
+
summary_fields = (('name', 'name'),
|
|
39
|
+
('description', 'description'),
|
|
40
|
+
('zone', 'zone'),
|
|
41
|
+
('status', 'status'),
|
|
42
|
+
('source-snapshot', 'sourceSnapshot'),
|
|
43
|
+
('size-gb', 'sizeGb'))
|
|
44
|
+
|
|
45
|
+
detail_fields = (('name', 'name'),
|
|
46
|
+
('description', 'description'),
|
|
47
|
+
('creation-time', 'creationTimestamp'),
|
|
48
|
+
('zone', 'zone'),
|
|
49
|
+
('status', 'status'),
|
|
50
|
+
('source-snapshot', 'sourceSnapshot'),
|
|
51
|
+
('size-gb', 'sizeGb'))
|
|
52
|
+
|
|
53
|
+
resource_collection_name = 'disks'
|
|
54
|
+
|
|
55
|
+
def __init__(self, name, flag_values):
|
|
56
|
+
super(DiskCommand, self).__init__(name, flag_values)
|
|
57
|
+
|
|
58
|
+
flags.DEFINE_string('zone',
|
|
59
|
+
None,
|
|
60
|
+
'The zone for this request.',
|
|
61
|
+
flag_values=flag_values)
|
|
62
|
+
|
|
63
|
+
def SetApi(self, api):
|
|
64
|
+
"""Set the Google Compute Engine API for the command.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
api: The Google Compute Engine API used by this command.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
None.
|
|
71
|
+
|
|
72
|
+
"""
|
|
73
|
+
self._disks_api = api.disks()
|
|
74
|
+
self._zones_api = api.zones()
|
|
75
|
+
|
|
76
|
+
def _PrepareRequestArgs(self, disk_name, **other_args):
|
|
77
|
+
"""Gets the dictionary of API method keyword arguments.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
disk_name: The name of the disk.
|
|
81
|
+
**other_args: Keyword arguments that should be included in the request.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Dictionary of keyword arguments that should be passed in the API call,
|
|
85
|
+
includes all keyword arguments passed in 'other_args' plus
|
|
86
|
+
common keys such as the name of the resource and the project.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
kwargs = {
|
|
90
|
+
'project': self._project,
|
|
91
|
+
'disk': self.DenormalizeResourceName(disk_name)
|
|
92
|
+
}
|
|
93
|
+
if self._IsUsingAtLeastApiVersion('v1beta14') and self._flags.zone:
|
|
94
|
+
kwargs['zone'] = self._flags.zone
|
|
95
|
+
for key, value in other_args.items():
|
|
96
|
+
kwargs[key] = value
|
|
97
|
+
return kwargs
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class AddDisk(DiskCommand):
|
|
101
|
+
"""Create new machine disks.
|
|
102
|
+
|
|
103
|
+
More than one disk name can be specified. Multiple disks will be created in
|
|
104
|
+
parallel.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
positional_args = '<disk-name-1> ... <disk-name-n>'
|
|
108
|
+
status_field = 'status'
|
|
109
|
+
_TERMINAL_STATUS = ['READY', 'FAILED']
|
|
110
|
+
|
|
111
|
+
def __init__(self, name, flag_values):
|
|
112
|
+
super(AddDisk, self).__init__(name, flag_values)
|
|
113
|
+
flags.DEFINE_string('description',
|
|
114
|
+
'',
|
|
115
|
+
'Disk description.',
|
|
116
|
+
flag_values=flag_values)
|
|
117
|
+
flags.DEFINE_integer('size_gb',
|
|
118
|
+
None,
|
|
119
|
+
'The size of the persistent disk in GB.',
|
|
120
|
+
flag_values=flag_values)
|
|
121
|
+
flags.DEFINE_string('source_snapshot',
|
|
122
|
+
None,
|
|
123
|
+
'The source snapshot for this disk.',
|
|
124
|
+
flag_values=flag_values)
|
|
125
|
+
flags.DEFINE_string('source_image',
|
|
126
|
+
None,
|
|
127
|
+
'The source image for this disk.',
|
|
128
|
+
flag_values=flag_values)
|
|
129
|
+
flags.DEFINE_boolean('wait_until_complete',
|
|
130
|
+
False,
|
|
131
|
+
'Whether the program should wait until the disk'
|
|
132
|
+
' is restored from snapshot.',
|
|
133
|
+
flag_values=flag_values)
|
|
134
|
+
|
|
135
|
+
def Handle(self, *disk_names):
|
|
136
|
+
"""Add the specified disks.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
*disk_names: The names of the disks to add.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
A tuple of (results, exceptions).
|
|
143
|
+
|
|
144
|
+
Raises:
|
|
145
|
+
CommandError: If the command is unsupported in this API version.
|
|
146
|
+
UsageError: If no disk names are specified.
|
|
147
|
+
"""
|
|
148
|
+
if not disk_names:
|
|
149
|
+
raise app.UsageError('Please specify at lease one disk name.')
|
|
150
|
+
|
|
151
|
+
self._flags.zone = self._GetZone(self._flags.zone)
|
|
152
|
+
zone = self.NormalizeTopLevelResourceName(self._project, 'zones',
|
|
153
|
+
self._flags.zone)
|
|
154
|
+
kind = self._GetResourceApiKind('disk')
|
|
155
|
+
|
|
156
|
+
source_image = None
|
|
157
|
+
if self._flags.source_image:
|
|
158
|
+
source_image = self.NormalizeGlobalResourceName(
|
|
159
|
+
self._project,
|
|
160
|
+
'images',
|
|
161
|
+
self._flags.source_image)
|
|
162
|
+
source_snapshot = None
|
|
163
|
+
if self._flags.source_snapshot:
|
|
164
|
+
source_snapshot = self.NormalizeGlobalResourceName(
|
|
165
|
+
self._project,
|
|
166
|
+
'snapshots',
|
|
167
|
+
self._flags.source_snapshot)
|
|
168
|
+
|
|
169
|
+
kwargs = {}
|
|
170
|
+
|
|
171
|
+
if self._IsUsingAtLeastApiVersion('v1beta14'):
|
|
172
|
+
kwargs['zone'] = self.DenormalizeResourceName(self._flags.zone)
|
|
173
|
+
|
|
174
|
+
requests = []
|
|
175
|
+
for name in disk_names:
|
|
176
|
+
disk = {
|
|
177
|
+
'kind': kind,
|
|
178
|
+
'name': self.DenormalizeResourceName(name),
|
|
179
|
+
'description': self._flags.description,
|
|
180
|
+
'zone': zone,
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if source_snapshot is not None:
|
|
184
|
+
disk['sourceSnapshot'] = source_snapshot
|
|
185
|
+
elif source_image is not None:
|
|
186
|
+
kwargs['sourceImage'] = source_image
|
|
187
|
+
if self._flags.size_gb:
|
|
188
|
+
disk['sizeGb'] = self._flags.size_gb
|
|
189
|
+
else:
|
|
190
|
+
disk['sizeGb'] = self._flags.size_gb or 10
|
|
191
|
+
if self._IsUsingAtLeastApiVersion('v1beta14'):
|
|
192
|
+
del disk['zone']
|
|
193
|
+
|
|
194
|
+
requests.append(self._disks_api.insert(project=self._project,
|
|
195
|
+
body=disk, **kwargs))
|
|
196
|
+
|
|
197
|
+
if self._flags.wait_until_complete and not self._flags.synchronous_mode:
|
|
198
|
+
LOGGER.warn('wait_until_complete specified. Implying synchronous_mode.')
|
|
199
|
+
self._flags.synchronous_mode = True
|
|
200
|
+
|
|
201
|
+
(results, exceptions) = self.ExecuteRequests(requests)
|
|
202
|
+
|
|
203
|
+
if self._flags.wait_until_complete:
|
|
204
|
+
awaiting = results
|
|
205
|
+
results = []
|
|
206
|
+
for result in awaiting:
|
|
207
|
+
if 'error' not in result:
|
|
208
|
+
result = self._WaitUntilDiskIsComplete(result)
|
|
209
|
+
results.append(result)
|
|
210
|
+
|
|
211
|
+
list_type = 'diskList' if self._flags.synchronous_mode else 'operationList'
|
|
212
|
+
return (self.MakeListResult(results, list_type), exceptions)
|
|
213
|
+
|
|
214
|
+
def _InternalGetDisk(self, disk_name):
|
|
215
|
+
"""A simple implementation of getting current disk state.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
disk_name: the name of the disk to get.
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
Json containing full disk information.
|
|
222
|
+
"""
|
|
223
|
+
disk_request = self._disks_api.get(**self._PrepareRequestArgs(disk_name))
|
|
224
|
+
return disk_request.execute()
|
|
225
|
+
|
|
226
|
+
def _WaitUntilDiskIsComplete(self, result):
|
|
227
|
+
"""Waits for the disk to complete.
|
|
228
|
+
|
|
229
|
+
Periodically polls the server for current disk status. Exits if the
|
|
230
|
+
status of the disk is READY or FAILED or the maximum waiting timeout
|
|
231
|
+
has been reached. In both cases returns the last known disk details.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
result: the current state of the disk.
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
Json containing full disk information.
|
|
238
|
+
"""
|
|
239
|
+
current_status = result[self.status_field]
|
|
240
|
+
disk_name = result['name']
|
|
241
|
+
start_time = time.time()
|
|
242
|
+
LOGGER.info('Will wait for restore for: %d seconds.',
|
|
243
|
+
self._flags.max_wait_time)
|
|
244
|
+
while (time.time() - start_time < self._flags.max_wait_time and
|
|
245
|
+
current_status not in self._TERMINAL_STATUS):
|
|
246
|
+
LOGGER.info(
|
|
247
|
+
'Waiting for disk. Current status: %s. Sleeping for %ss.',
|
|
248
|
+
current_status, self._flags.sleep_between_polls)
|
|
249
|
+
time.sleep(self._flags.sleep_between_polls)
|
|
250
|
+
result = self._InternalGetDisk(disk_name)
|
|
251
|
+
current_status = result[self.status_field]
|
|
252
|
+
if current_status not in self._TERMINAL_STATUS:
|
|
253
|
+
LOGGER.warn('Timeout reached. Disk %s has not yet been restored.',
|
|
254
|
+
disk_name)
|
|
255
|
+
return result
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class GetDisk(DiskCommand):
|
|
259
|
+
"""Get a machine disk."""
|
|
260
|
+
|
|
261
|
+
positional_args = '<disk-name>'
|
|
262
|
+
|
|
263
|
+
def __init__(self, name, flag_values):
|
|
264
|
+
super(GetDisk, self).__init__(name, flag_values)
|
|
265
|
+
|
|
266
|
+
def Handle(self, disk_name):
|
|
267
|
+
"""Get the specified disk.
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
disk_name: The name of the disk to get
|
|
271
|
+
|
|
272
|
+
Returns:
|
|
273
|
+
The result of getting the disk.
|
|
274
|
+
"""
|
|
275
|
+
if self._IsUsingAtLeastApiVersion('v1beta14') and not self._flags.zone:
|
|
276
|
+
self._flags.zone = self.GetZoneForResource(self._disks_api,
|
|
277
|
+
disk_name)
|
|
278
|
+
|
|
279
|
+
disk_request = self._disks_api.get(**self._PrepareRequestArgs(disk_name))
|
|
280
|
+
return disk_request.execute()
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
class DeleteDisk(DiskCommand):
|
|
284
|
+
"""Delete one or more machine disks.
|
|
285
|
+
|
|
286
|
+
If multiple disk names are specified, the disks will be deleted in parallel.
|
|
287
|
+
"""
|
|
288
|
+
|
|
289
|
+
positional_args = '<disk-name-1> ... <disk-name-n>'
|
|
290
|
+
safety_prompt = 'Delete disk'
|
|
291
|
+
|
|
292
|
+
def __init__(self, name, flag_values):
|
|
293
|
+
super(DeleteDisk, self).__init__(name, flag_values)
|
|
294
|
+
|
|
295
|
+
def Handle(self, *disk_names):
|
|
296
|
+
"""Delete the specified disks.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
*disk_names: The names of the disks to delete
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
Tuple (results, exceptions) - result of deleting the disks.
|
|
303
|
+
"""
|
|
304
|
+
if self._IsUsingAtLeastApiVersion('v1beta14') and not self._flags.zone:
|
|
305
|
+
if len(disk_names) > 1:
|
|
306
|
+
self._flags.zone = self._GetZone()
|
|
307
|
+
else:
|
|
308
|
+
self._flags.zone = self.GetZoneForResource(self._disks_api,
|
|
309
|
+
disk_names[0])
|
|
310
|
+
requests = []
|
|
311
|
+
for disk_name in disk_names:
|
|
312
|
+
requests.append(self._disks_api.delete(
|
|
313
|
+
**self._PrepareRequestArgs(disk_name)))
|
|
314
|
+
results, exceptions = self.ExecuteRequests(requests)
|
|
315
|
+
return (self.MakeListResult(results, 'operationList'), exceptions)
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
class ListDisks(DiskCommand, command_base.GoogleComputeListCommand):
|
|
319
|
+
"""List the disks for a project."""
|
|
320
|
+
|
|
321
|
+
is_global_level_collection = False
|
|
322
|
+
is_zone_level_collection = True
|
|
323
|
+
|
|
324
|
+
def __init__(self, name, flag_values):
|
|
325
|
+
super(ListDisks, self).__init__(name, flag_values)
|
|
326
|
+
|
|
327
|
+
def ListFunc(self):
|
|
328
|
+
"""Returns the function for listing disks."""
|
|
329
|
+
if self._IsUsingAtLeastApiVersion('v1beta14'):
|
|
330
|
+
return None
|
|
331
|
+
return self._disks_api.list
|
|
332
|
+
|
|
333
|
+
def ListZoneFunc(self):
|
|
334
|
+
"""Returns the function for listing disks in a zone."""
|
|
335
|
+
return self._disks_api.list
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def AddCommands():
|
|
339
|
+
appcommands.AddCmd('adddisk', AddDisk)
|
|
340
|
+
appcommands.AddCmd('getdisk', GetDisk)
|
|
341
|
+
appcommands.AddCmd('deletedisk', DeleteDisk)
|
|
342
|
+
appcommands.AddCmd('listdisks', ListDisks)
|
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2012 Google Inc. All Rights Reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
"""Unit tests for the persistent disk commands."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
import path_initializer
|
|
22
|
+
path_initializer.InitializeSysPath()
|
|
23
|
+
|
|
24
|
+
import copy
|
|
25
|
+
import sys
|
|
26
|
+
|
|
27
|
+
from google.apputils import app
|
|
28
|
+
import gflags as flags
|
|
29
|
+
import unittest
|
|
30
|
+
|
|
31
|
+
from gcutil import command_base
|
|
32
|
+
from gcutil import disk_cmds
|
|
33
|
+
from gcutil import mock_api
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
FLAGS = flags.FLAGS
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class DiskCmdsTest(unittest.TestCase):
|
|
40
|
+
|
|
41
|
+
def _DoTestAddDiskGeneratesCorrectRequest(self, service_version):
|
|
42
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
43
|
+
|
|
44
|
+
command = disk_cmds.AddDisk('adddisk', flag_values)
|
|
45
|
+
|
|
46
|
+
expected_project = 'test_project'
|
|
47
|
+
expected_disk = 'test_disk'
|
|
48
|
+
expected_description = 'test disk'
|
|
49
|
+
submitted_zone = 'copernicus-moon-base'
|
|
50
|
+
expected_size = 20
|
|
51
|
+
flag_values.service_version = service_version
|
|
52
|
+
flag_values.zone = submitted_zone
|
|
53
|
+
flag_values.project = expected_project
|
|
54
|
+
flag_values.size_gb = expected_size
|
|
55
|
+
flag_values.description = expected_description
|
|
56
|
+
|
|
57
|
+
command.SetFlags(flag_values)
|
|
58
|
+
command.SetApi(mock_api.MockApi())
|
|
59
|
+
command._credential = mock_api.MockCredential()
|
|
60
|
+
|
|
61
|
+
results, exceptions = command.Handle(expected_disk)
|
|
62
|
+
self.assertEqual(len(results['items']), 1)
|
|
63
|
+
self.assertEqual(exceptions, [])
|
|
64
|
+
result = results['items'][0]
|
|
65
|
+
|
|
66
|
+
expected_zone = command.NormalizeTopLevelResourceName(
|
|
67
|
+
expected_project,
|
|
68
|
+
'zones',
|
|
69
|
+
submitted_zone)
|
|
70
|
+
|
|
71
|
+
self.assertEqual(result['project'], expected_project)
|
|
72
|
+
self.assertEqual(result['body']['name'], expected_disk)
|
|
73
|
+
self.assertEqual(result['body']['description'], expected_description)
|
|
74
|
+
self.assertEqual(result['body']['sizeGb'], expected_size)
|
|
75
|
+
if command._IsUsingAtLeastApiVersion('v1beta14'):
|
|
76
|
+
self.assertEqual(submitted_zone, result['zone'])
|
|
77
|
+
self.assertFalse('zone' in result['body'])
|
|
78
|
+
else:
|
|
79
|
+
self.assertEqual(result['body']['zone'], expected_zone)
|
|
80
|
+
self.assertFalse('zone' in result)
|
|
81
|
+
|
|
82
|
+
def testAddDiskGeneratesCorrectRequest(self):
|
|
83
|
+
for version in command_base.SUPPORTED_VERSIONS:
|
|
84
|
+
self._DoTestAddDiskGeneratesCorrectRequest(version)
|
|
85
|
+
|
|
86
|
+
def _DoTestAddMultipleDisks(self, service_version):
|
|
87
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
88
|
+
command = disk_cmds.AddDisk('adddisk', flag_values)
|
|
89
|
+
|
|
90
|
+
expected_kind = command._GetResourceApiKind('disk')
|
|
91
|
+
expected_project = 'test_project'
|
|
92
|
+
expected_disks = ['test-disk-%02d' % i for i in xrange(100)]
|
|
93
|
+
expected_description = 'test disk'
|
|
94
|
+
submitted_zone = 'copernicus-moon-base'
|
|
95
|
+
expected_size = 12
|
|
96
|
+
|
|
97
|
+
flag_values.service_version = service_version
|
|
98
|
+
flag_values.zone = submitted_zone
|
|
99
|
+
flag_values.project = expected_project
|
|
100
|
+
flag_values.size_gb = expected_size
|
|
101
|
+
flag_values.description = expected_description
|
|
102
|
+
|
|
103
|
+
command.SetFlags(flag_values)
|
|
104
|
+
command.SetApi(mock_api.MockApi())
|
|
105
|
+
command._credential = mock_api.MockCredential()
|
|
106
|
+
|
|
107
|
+
expected_zone = command.NormalizeTopLevelResourceName(
|
|
108
|
+
expected_project, 'zones', submitted_zone)
|
|
109
|
+
|
|
110
|
+
results, exceptions = command.Handle(*expected_disks)
|
|
111
|
+
self.assertEqual(exceptions, [])
|
|
112
|
+
results = results['items']
|
|
113
|
+
self.assertEqual(len(results), len(expected_disks))
|
|
114
|
+
|
|
115
|
+
for expected_disk, result in zip(expected_disks, results):
|
|
116
|
+
self.assertEqual(result['project'], expected_project)
|
|
117
|
+
self.assertEqual(result['body']['kind'], expected_kind)
|
|
118
|
+
self.assertEqual(result['body']['sizeGb'], expected_size)
|
|
119
|
+
self.assertEqual(result['body']['name'], expected_disk)
|
|
120
|
+
self.assertEqual(result['body']['description'], expected_description)
|
|
121
|
+
if command._IsUsingAtLeastApiVersion('v1beta14'):
|
|
122
|
+
self.assertEqual(submitted_zone, result['zone'])
|
|
123
|
+
self.assertFalse('zone' in result['body'])
|
|
124
|
+
else:
|
|
125
|
+
self.assertFalse('zone' in result)
|
|
126
|
+
self.assertEqual(result['body']['zone'], expected_zone)
|
|
127
|
+
|
|
128
|
+
def testAddMultipleDisks(self):
|
|
129
|
+
for version in command_base.SUPPORTED_VERSIONS:
|
|
130
|
+
self._DoTestAddMultipleDisks(version)
|
|
131
|
+
|
|
132
|
+
def _DoTestAddDiskFromSnapshotGeneratesCorrectRequest(self, service_version):
|
|
133
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
134
|
+
|
|
135
|
+
command = disk_cmds.AddDisk('adddisk', flag_values)
|
|
136
|
+
|
|
137
|
+
expected_project = 'test_project'
|
|
138
|
+
expected_disk = 'test_disk'
|
|
139
|
+
expected_description = 'test disk'
|
|
140
|
+
submitted_zone = 'copernicus-moon-base'
|
|
141
|
+
submitted_source_snapshot = 'snap1'
|
|
142
|
+
flag_values.service_version = service_version
|
|
143
|
+
flag_values.zone = submitted_zone
|
|
144
|
+
flag_values.project = expected_project
|
|
145
|
+
flag_values.description = expected_description
|
|
146
|
+
flag_values.source_snapshot = submitted_source_snapshot
|
|
147
|
+
|
|
148
|
+
command.SetFlags(flag_values)
|
|
149
|
+
command.SetApi(mock_api.MockApi())
|
|
150
|
+
command._credential = mock_api.MockCredential()
|
|
151
|
+
|
|
152
|
+
results, exceptions = command.Handle(expected_disk)
|
|
153
|
+
self.assertEqual(len(results['items']), 1)
|
|
154
|
+
self.assertEqual(exceptions, [])
|
|
155
|
+
result = results['items'][0]
|
|
156
|
+
|
|
157
|
+
expected_zone = command.NormalizeTopLevelResourceName(
|
|
158
|
+
expected_project,
|
|
159
|
+
'zones',
|
|
160
|
+
submitted_zone)
|
|
161
|
+
|
|
162
|
+
expected_source_snapshot = command.NormalizeGlobalResourceName(
|
|
163
|
+
expected_project,
|
|
164
|
+
'snapshots',
|
|
165
|
+
submitted_source_snapshot)
|
|
166
|
+
if command._IsUsingAtLeastApiVersion('v1beta14'):
|
|
167
|
+
self.assertEqual(submitted_zone, result['zone'])
|
|
168
|
+
self.assertFalse('zone' in result['body'])
|
|
169
|
+
else:
|
|
170
|
+
self.assertFalse('zone' in result)
|
|
171
|
+
self.assertEqual(result['body']['zone'], expected_zone)
|
|
172
|
+
|
|
173
|
+
self.assertEqual(result['project'], expected_project)
|
|
174
|
+
self.assertEqual(result['body']['name'], expected_disk)
|
|
175
|
+
self.assertEqual(result['body']['description'], expected_description)
|
|
176
|
+
self.assertEqual(result['body']['sourceSnapshot'], expected_source_snapshot)
|
|
177
|
+
|
|
178
|
+
def testAddDiskFromSnapshotGeneratesCorrectRequest(self):
|
|
179
|
+
for version in command_base.SUPPORTED_VERSIONS:
|
|
180
|
+
self._DoTestAddDiskFromSnapshotGeneratesCorrectRequest(version)
|
|
181
|
+
|
|
182
|
+
def testAddDiskDefaultSizeGb(self):
|
|
183
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
184
|
+
|
|
185
|
+
command = disk_cmds.AddDisk('adddisk', flag_values)
|
|
186
|
+
|
|
187
|
+
flag_values.zone = 'copernicus-moon-base'
|
|
188
|
+
flag_values.project = 'test_project'
|
|
189
|
+
|
|
190
|
+
command.SetFlags(flag_values)
|
|
191
|
+
command.SetApi(mock_api.MockApi())
|
|
192
|
+
command._credential = mock_api.MockCredential()
|
|
193
|
+
|
|
194
|
+
results, exceptions = command.Handle('disk1')
|
|
195
|
+
self.assertEqual(len(results['items']), 1)
|
|
196
|
+
self.assertEqual(exceptions, [])
|
|
197
|
+
result = results['items'][0]
|
|
198
|
+
|
|
199
|
+
# We did not set the size, make sure it defaults to 10GB.
|
|
200
|
+
self.assertEqual(10, result['body']['sizeGb'])
|
|
201
|
+
|
|
202
|
+
def testAddDiskFromImageDoesNotPassSizeGbUnlessExplicitlySet(self):
|
|
203
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
204
|
+
|
|
205
|
+
command = disk_cmds.AddDisk('adddisk', flag_values)
|
|
206
|
+
|
|
207
|
+
flag_values.zone = 'copernicus-moon-base'
|
|
208
|
+
flag_values.project = 'test_project'
|
|
209
|
+
flag_values.source_image = 'image1'
|
|
210
|
+
flag_values.service_version = 'v1beta14'
|
|
211
|
+
|
|
212
|
+
command.SetFlags(flag_values)
|
|
213
|
+
command.SetApi(mock_api.MockApi())
|
|
214
|
+
command._credential = mock_api.MockCredential()
|
|
215
|
+
|
|
216
|
+
results, exceptions = command.Handle('disk1')
|
|
217
|
+
self.assertEqual(len(results['items']), 1)
|
|
218
|
+
self.assertEqual(exceptions, [])
|
|
219
|
+
result = results['items'][0]
|
|
220
|
+
|
|
221
|
+
# Make sure we did not pass 'sizeGb' in the body.
|
|
222
|
+
self.assertFalse('sizeGb' in result['body'])
|
|
223
|
+
|
|
224
|
+
def _DoTestAddDiskFromImageGeneratesCorrectRequest(self, service_version):
|
|
225
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
226
|
+
|
|
227
|
+
command = disk_cmds.AddDisk('adddisk', flag_values)
|
|
228
|
+
|
|
229
|
+
expected_project = 'test_project'
|
|
230
|
+
expected_disk = 'test_disk'
|
|
231
|
+
expected_description = 'test disk'
|
|
232
|
+
expected_size_gb = 123
|
|
233
|
+
submitted_zone = 'copernicus-moon-base'
|
|
234
|
+
submitted_source_image = 'image1'
|
|
235
|
+
submitted_size_gb = 123
|
|
236
|
+
flag_values.zone = submitted_zone
|
|
237
|
+
flag_values.project = expected_project
|
|
238
|
+
flag_values.description = expected_description
|
|
239
|
+
flag_values.source_image = submitted_source_image
|
|
240
|
+
flag_values.size_gb = submitted_size_gb
|
|
241
|
+
flag_values.service_version = service_version
|
|
242
|
+
|
|
243
|
+
command.SetFlags(flag_values)
|
|
244
|
+
command.SetApi(mock_api.MockApi())
|
|
245
|
+
command._credential = mock_api.MockCredential()
|
|
246
|
+
|
|
247
|
+
results, exceptions = command.Handle(expected_disk)
|
|
248
|
+
self.assertEqual(len(results['items']), 1)
|
|
249
|
+
self.assertEqual(exceptions, [])
|
|
250
|
+
result = results['items'][0]
|
|
251
|
+
|
|
252
|
+
expected_zone = command.NormalizeTopLevelResourceName(
|
|
253
|
+
expected_project,
|
|
254
|
+
'zones',
|
|
255
|
+
submitted_zone)
|
|
256
|
+
|
|
257
|
+
expected_source_image = command.NormalizeGlobalResourceName(
|
|
258
|
+
expected_project,
|
|
259
|
+
'images',
|
|
260
|
+
submitted_source_image)
|
|
261
|
+
|
|
262
|
+
self.assertEqual(result['project'], expected_project)
|
|
263
|
+
self.assertEqual(result['body']['name'], expected_disk)
|
|
264
|
+
self.assertEqual(result['body']['description'], expected_description)
|
|
265
|
+
self.assertEqual(result['body']['sizeGb'], expected_size_gb)
|
|
266
|
+
self.assertEqual(result['sourceImage'], expected_source_image)
|
|
267
|
+
if command._IsUsingAtLeastApiVersion('v1beta14'):
|
|
268
|
+
self.assertEqual(submitted_zone, result['zone'])
|
|
269
|
+
self.assertFalse('zone' in result['body'])
|
|
270
|
+
else:
|
|
271
|
+
self.assertEqual(result['body']['zone'], expected_zone)
|
|
272
|
+
self.assertFalse('zone' in result)
|
|
273
|
+
|
|
274
|
+
def testAddDiskFromImageGeneratesCorrectRequest(self):
|
|
275
|
+
for version in command_base.SUPPORTED_VERSIONS:
|
|
276
|
+
self._DoTestAddDiskFromImageGeneratesCorrectRequest(version)
|
|
277
|
+
|
|
278
|
+
def testAddDiskWithKernelGeneratesCorrectRequest(self):
|
|
279
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
280
|
+
|
|
281
|
+
command = disk_cmds.AddDisk('adddisk', flag_values)
|
|
282
|
+
|
|
283
|
+
expected_project = 'test_project'
|
|
284
|
+
expected_disk = 'test_disk'
|
|
285
|
+
expected_description = 'test disk'
|
|
286
|
+
expected_size_gb = 123
|
|
287
|
+
submitted_zone = 'copernicus-moon-base'
|
|
288
|
+
submitted_size_gb = 123
|
|
289
|
+
flag_values.zone = submitted_zone
|
|
290
|
+
flag_values.project = expected_project
|
|
291
|
+
flag_values.description = expected_description
|
|
292
|
+
flag_values.size_gb = submitted_size_gb
|
|
293
|
+
|
|
294
|
+
command.SetFlags(flag_values)
|
|
295
|
+
command.SetApi(mock_api.MockApi())
|
|
296
|
+
command._credential = mock_api.MockCredential()
|
|
297
|
+
|
|
298
|
+
results, exceptions = command.Handle(expected_disk)
|
|
299
|
+
self.assertEqual(len(results['items']), 1)
|
|
300
|
+
self.assertEqual(exceptions, [])
|
|
301
|
+
result = results['items'][0]
|
|
302
|
+
|
|
303
|
+
expected_zone = command.NormalizeTopLevelResourceName(
|
|
304
|
+
expected_project,
|
|
305
|
+
'zones',
|
|
306
|
+
submitted_zone)
|
|
307
|
+
|
|
308
|
+
self.assertEqual(result['project'], expected_project)
|
|
309
|
+
self.assertEqual(result['body']['name'], expected_disk)
|
|
310
|
+
self.assertEqual(result['body']['description'], expected_description)
|
|
311
|
+
self.assertEqual(result['body']['sizeGb'], expected_size_gb)
|
|
312
|
+
if command._IsUsingAtLeastApiVersion('v1beta14'):
|
|
313
|
+
self.assertEqual(submitted_zone, result['zone'])
|
|
314
|
+
self.assertFalse('zone' in result['body'])
|
|
315
|
+
else:
|
|
316
|
+
self.assertFalse('zone' in result)
|
|
317
|
+
self.assertEqual(result['body']['zone'], expected_zone)
|
|
318
|
+
|
|
319
|
+
def testAddDiskRequiresZone(self):
|
|
320
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
321
|
+
|
|
322
|
+
command = disk_cmds.AddDisk('adddisk', flag_values)
|
|
323
|
+
|
|
324
|
+
expected_project = 'test_project'
|
|
325
|
+
expected_disk = 'test_disk'
|
|
326
|
+
expected_description = 'test disk'
|
|
327
|
+
expected_size = 20
|
|
328
|
+
submitted_version = command_base.CURRENT_VERSION
|
|
329
|
+
submitted_zone = 'us-east-a'
|
|
330
|
+
|
|
331
|
+
flag_values.service_version = submitted_version
|
|
332
|
+
flag_values.project = expected_project
|
|
333
|
+
flag_values.size_gb = expected_size
|
|
334
|
+
flag_values.description = expected_description
|
|
335
|
+
|
|
336
|
+
command.SetFlags(flag_values)
|
|
337
|
+
|
|
338
|
+
zones = {'items': [{'name': 'us-east-a'},
|
|
339
|
+
{'name': 'us-east-b'},
|
|
340
|
+
{'name': 'us-east-c'},
|
|
341
|
+
{'name': 'us-west-a'}]}
|
|
342
|
+
|
|
343
|
+
class MockZonesApi(object):
|
|
344
|
+
def list(self, **unused_kwargs):
|
|
345
|
+
return mock_api.MockRequest(zones)
|
|
346
|
+
|
|
347
|
+
api = mock_api.MockApi()
|
|
348
|
+
api.zones = MockZonesApi
|
|
349
|
+
command.SetApi(api)
|
|
350
|
+
command._credential = mock_api.MockCredential()
|
|
351
|
+
|
|
352
|
+
expected_zone = command.NormalizeTopLevelResourceName(
|
|
353
|
+
expected_project,
|
|
354
|
+
'zones',
|
|
355
|
+
submitted_zone)
|
|
356
|
+
|
|
357
|
+
mock_output = mock_api.MockOutput()
|
|
358
|
+
mock_input = mock_api.MockInput('1\n\r')
|
|
359
|
+
oldin = sys.stdin
|
|
360
|
+
sys.stdin = mock_input
|
|
361
|
+
oldout = sys.stdout
|
|
362
|
+
sys.stdout = mock_output
|
|
363
|
+
|
|
364
|
+
results, exceptions = command.Handle(expected_disk)
|
|
365
|
+
self.assertEqual(len(results['items']), 1)
|
|
366
|
+
self.assertEqual(exceptions, [])
|
|
367
|
+
result = results['items'][0]
|
|
368
|
+
|
|
369
|
+
if command._IsUsingAtLeastApiVersion('v1beta14'):
|
|
370
|
+
self.assertEqual(submitted_zone, result['zone'])
|
|
371
|
+
self.assertFalse('zone' in result['body'])
|
|
372
|
+
else:
|
|
373
|
+
self.assertFalse('zone' in result)
|
|
374
|
+
self.assertEqual(result['body']['zone'], expected_zone)
|
|
375
|
+
|
|
376
|
+
sys.stdin = oldin
|
|
377
|
+
sys.stdout = oldout
|
|
378
|
+
|
|
379
|
+
def _DoTestGetDiskGeneratesCorrectRequest(self, service_version):
|
|
380
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
381
|
+
|
|
382
|
+
command = disk_cmds.GetDisk('getdisk', flag_values)
|
|
383
|
+
|
|
384
|
+
expected_project = 'test_project'
|
|
385
|
+
expected_disk = 'test_disk'
|
|
386
|
+
flag_values.project = expected_project
|
|
387
|
+
flag_values.service_version = service_version
|
|
388
|
+
flag_values.zone = 'zone-a'
|
|
389
|
+
|
|
390
|
+
command.SetFlags(flag_values)
|
|
391
|
+
command.SetApi(mock_api.MockApi())
|
|
392
|
+
command._credential = mock_api.MockCredential()
|
|
393
|
+
submitted_zone = 'copernicus-moon-base'
|
|
394
|
+
if command._IsUsingAtLeastApiVersion('v1beta14'):
|
|
395
|
+
flag_values.zone = submitted_zone
|
|
396
|
+
|
|
397
|
+
result = command.Handle(expected_disk)
|
|
398
|
+
|
|
399
|
+
self.assertEqual(result['project'], expected_project)
|
|
400
|
+
self.assertEqual(result['disk'], expected_disk)
|
|
401
|
+
if command._IsUsingAtLeastApiVersion('v1beta14'):
|
|
402
|
+
self.assertEqual(submitted_zone, result['zone'])
|
|
403
|
+
else:
|
|
404
|
+
self.assertFalse('zone' in result)
|
|
405
|
+
|
|
406
|
+
def testGetDiskGeneratesCorrectRequest(self):
|
|
407
|
+
for version in command_base.SUPPORTED_VERSIONS:
|
|
408
|
+
self._DoTestGetDiskGeneratesCorrectRequest(version)
|
|
409
|
+
|
|
410
|
+
def _DoTestDeleteDiskGeneratesCorrectRequest(self, service_version):
|
|
411
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
412
|
+
|
|
413
|
+
command = disk_cmds.DeleteDisk('deletedisk', flag_values)
|
|
414
|
+
|
|
415
|
+
expected_project = 'test_project'
|
|
416
|
+
expected_disk = 'test_disk'
|
|
417
|
+
flag_values.project = expected_project
|
|
418
|
+
flag_values.zone = 'zone-a'
|
|
419
|
+
|
|
420
|
+
command.SetFlags(flag_values)
|
|
421
|
+
command.SetApi(mock_api.MockApi())
|
|
422
|
+
flag_values.service_version = service_version
|
|
423
|
+
submitted_zone = 'copernicus-moon-base'
|
|
424
|
+
if command._IsUsingAtLeastApiVersion('v1beta14'):
|
|
425
|
+
flag_values.zone = submitted_zone
|
|
426
|
+
|
|
427
|
+
command._credential = mock_api.MockCredential()
|
|
428
|
+
|
|
429
|
+
results, exceptions = command.Handle(expected_disk)
|
|
430
|
+
self.assertEqual(len(results['items']), 1)
|
|
431
|
+
self.assertEqual(exceptions, [])
|
|
432
|
+
result = results['items'][0]
|
|
433
|
+
|
|
434
|
+
self.assertEqual(result['project'], expected_project)
|
|
435
|
+
self.assertEqual(result['disk'], expected_disk)
|
|
436
|
+
if command._IsUsingAtLeastApiVersion('v1beta14'):
|
|
437
|
+
self.assertEqual(submitted_zone, result['zone'])
|
|
438
|
+
else:
|
|
439
|
+
self.assertFalse('zone' in result)
|
|
440
|
+
|
|
441
|
+
def testDeleteDiskGeneratesCorrectRequest(self):
|
|
442
|
+
for version in command_base.SUPPORTED_VERSIONS:
|
|
443
|
+
self._DoTestDeleteDiskGeneratesCorrectRequest(version)
|
|
444
|
+
|
|
445
|
+
def testDeleteMultipleDisks(self):
|
|
446
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
447
|
+
command = disk_cmds.DeleteDisk('deletedisk', flag_values)
|
|
448
|
+
|
|
449
|
+
expected_project = 'test_project'
|
|
450
|
+
expected_disks = ['test-disk-%02d' % x for x in xrange(100)]
|
|
451
|
+
flag_values.project = expected_project
|
|
452
|
+
flag_values.zone = 'zone-a'
|
|
453
|
+
|
|
454
|
+
command.SetFlags(flag_values)
|
|
455
|
+
command.SetApi(mock_api.MockApi())
|
|
456
|
+
command._credential = mock_api.MockCredential()
|
|
457
|
+
|
|
458
|
+
results, exceptions = command.Handle(*expected_disks)
|
|
459
|
+
self.assertEqual(exceptions, [])
|
|
460
|
+
results = results['items']
|
|
461
|
+
self.assertEqual(len(results), len(expected_disks))
|
|
462
|
+
|
|
463
|
+
for expected_disk, result in zip(expected_disks, results):
|
|
464
|
+
self.assertEqual(result['project'], expected_project)
|
|
465
|
+
self.assertEqual(result['disk'], expected_disk)
|
|
466
|
+
|
|
467
|
+
def testAddWithNoDisk(self):
|
|
468
|
+
flag_values = copy.deepcopy(FLAGS)
|
|
469
|
+
command = disk_cmds.AddDisk('adddisk', flag_values)
|
|
470
|
+
self.assertRaises(app.UsageError, command.Handle)
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
if __name__ == '__main__':
|
|
474
|
+
unittest.main()
|