gcloud 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data.tar.gz.sig +2 -3
  2. data/CHANGELOG +4 -0
  3. data/LICENSE +674 -0
  4. data/Manifest +111 -0
  5. data/README.md +4 -3
  6. data/bin/gcutil +53 -0
  7. data/gcloud.gemspec +4 -3
  8. data/packages/gcutil-1.7.1/CHANGELOG +197 -0
  9. data/packages/gcutil-1.7.1/LICENSE +202 -0
  10. data/packages/gcutil-1.7.1/VERSION +1 -0
  11. data/packages/gcutil-1.7.1/gcutil +53 -0
  12. data/packages/gcutil-1.7.1/lib/google_api_python_client/LICENSE +23 -0
  13. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/__init__.py +1 -0
  14. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/discovery.py +743 -0
  15. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/errors.py +123 -0
  16. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/ext/__init__.py +0 -0
  17. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/http.py +1443 -0
  18. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/mimeparse.py +172 -0
  19. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/model.py +385 -0
  20. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/schema.py +303 -0
  21. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/__init__.py +1 -0
  22. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/anyjson.py +32 -0
  23. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/appengine.py +528 -0
  24. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/client.py +1139 -0
  25. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/clientsecrets.py +105 -0
  26. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/crypt.py +244 -0
  27. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/django_orm.py +124 -0
  28. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/file.py +107 -0
  29. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/locked_file.py +343 -0
  30. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/multistore_file.py +379 -0
  31. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/tools.py +174 -0
  32. data/packages/gcutil-1.7.1/lib/google_api_python_client/uritemplate/__init__.py +147 -0
  33. data/packages/gcutil-1.7.1/lib/google_apputils/LICENSE +202 -0
  34. data/packages/gcutil-1.7.1/lib/google_apputils/google/__init__.py +3 -0
  35. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/__init__.py +3 -0
  36. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/app.py +356 -0
  37. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.py +783 -0
  38. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/basetest.py +1260 -0
  39. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/datelib.py +421 -0
  40. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/debug.py +60 -0
  41. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/file_util.py +181 -0
  42. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/resources.py +67 -0
  43. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/run_script_module.py +217 -0
  44. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/setup_command.py +159 -0
  45. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/shellutil.py +49 -0
  46. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/stopwatch.py +204 -0
  47. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/__init__.py +0 -0
  48. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auth_helper.py +140 -0
  49. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auth_helper_test.py +149 -0
  50. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auto_auth.py +130 -0
  51. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auto_auth_test.py +75 -0
  52. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/basic_cmds.py +128 -0
  53. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/basic_cmds_test.py +111 -0
  54. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/command_base.py +1808 -0
  55. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/command_base_test.py +1651 -0
  56. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/compute/v1beta13.json +2851 -0
  57. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/compute/v1beta14.json +3361 -0
  58. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/disk_cmds.py +342 -0
  59. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/disk_cmds_test.py +474 -0
  60. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/firewall_cmds.py +344 -0
  61. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/firewall_cmds_test.py +231 -0
  62. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/flags_cache.py +274 -0
  63. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/gcutil +89 -0
  64. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/gcutil_logging.py +69 -0
  65. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/image_cmds.py +262 -0
  66. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/image_cmds_test.py +172 -0
  67. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/instance_cmds.py +1506 -0
  68. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/instance_cmds_test.py +1904 -0
  69. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/kernel_cmds.py +91 -0
  70. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/kernel_cmds_test.py +56 -0
  71. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/machine_type_cmds.py +106 -0
  72. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/machine_type_cmds_test.py +59 -0
  73. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata.py +96 -0
  74. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata_lib.py +357 -0
  75. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata_test.py +84 -0
  76. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/mock_api.py +420 -0
  77. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/mock_metadata.py +58 -0
  78. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/move_cmds.py +824 -0
  79. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/move_cmds_test.py +307 -0
  80. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/network_cmds.py +178 -0
  81. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/network_cmds_test.py +133 -0
  82. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/operation_cmds.py +181 -0
  83. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/operation_cmds_test.py +196 -0
  84. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/path_initializer.py +38 -0
  85. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/project_cmds.py +173 -0
  86. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/project_cmds_test.py +111 -0
  87. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/scopes.py +61 -0
  88. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/scopes_test.py +50 -0
  89. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/snapshot_cmds.py +276 -0
  90. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/snapshot_cmds_test.py +260 -0
  91. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/ssh_keys.py +266 -0
  92. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/ssh_keys_test.py +128 -0
  93. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/table_formatter.py +563 -0
  94. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/thread_pool.py +188 -0
  95. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/thread_pool_test.py +88 -0
  96. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/utils.py +208 -0
  97. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/utils_test.py +193 -0
  98. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version.py +17 -0
  99. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version_checker.py +246 -0
  100. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version_checker_test.py +271 -0
  101. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/zone_cmds.py +151 -0
  102. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/zone_cmds_test.py +60 -0
  103. data/packages/gcutil-1.7.1/lib/httplib2/LICENSE +21 -0
  104. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/__init__.py +1630 -0
  105. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/cacerts.txt +714 -0
  106. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/iri2uri.py +110 -0
  107. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/socks.py +438 -0
  108. data/packages/gcutil-1.7.1/lib/iso8601/LICENSE +20 -0
  109. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/__init__.py +1 -0
  110. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/iso8601.py +102 -0
  111. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/test_iso8601.py +111 -0
  112. data/packages/gcutil-1.7.1/lib/python_gflags/AUTHORS +2 -0
  113. data/packages/gcutil-1.7.1/lib/python_gflags/LICENSE +28 -0
  114. data/packages/gcutil-1.7.1/lib/python_gflags/gflags.py +2862 -0
  115. data/packages/gcutil-1.7.1/lib/python_gflags/gflags2man.py +544 -0
  116. data/packages/gcutil-1.7.1/lib/python_gflags/gflags_validators.py +187 -0
  117. metadata +118 -5
  118. metadata.gz.sig +0 -0
@@ -0,0 +1,307 @@
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 move commands."""
18
+
19
+
20
+
21
+ import path_initializer
22
+ path_initializer.InitializeSysPath()
23
+
24
+ import copy
25
+ import uuid
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 mock_api
33
+ from gcutil import move_cmds
34
+
35
+ FLAGS = flags.FLAGS
36
+
37
+ class MoveInstancesBaseTestCase(unittest.TestCase):
38
+
39
+ def setUp(self):
40
+ self.flag_values = copy.deepcopy(FLAGS)
41
+ self.command = self._CreateCommand()
42
+ self.api = mock_api.MockApi()
43
+ self.command.SetFlags(self.flag_values)
44
+ self.command.SetApi(self.api)
45
+
46
+ def _CreateCommand(self):
47
+ return move_cmds.MoveInstances('basemoveinstances', self.flag_values)
48
+
49
+ class MoveInstancesBaseTest(MoveInstancesBaseTestCase):
50
+
51
+ cmd_name = 'moveinstancesbase'
52
+
53
+ def testExtractAvailableQuota(self):
54
+ project_quota = [
55
+ {'metric': 'INSTANCES',
56
+ 'usage': 5.0,
57
+ 'limit': 10.0},
58
+ {'metric': 'CPUS',
59
+ 'usage': 40.0,
60
+ 'limit': 0}, # Quota was changed after resource-creation.
61
+ {'metric': 'EPHEMERAL_ADDRESSES',
62
+ 'usage': 5.0,
63
+ 'limit': 10.0},
64
+ {'metric': 'DISKS',
65
+ 'usage': 7.0,
66
+ 'limit': 10.0},
67
+ {'metric': 'DISKS_TOTAL_GB',
68
+ 'usage': 40.0,
69
+ 'limit': 100.0},
70
+ {'metric': 'SNAPSHOTS',
71
+ 'usage': 3.0,
72
+ 'limit': 100.0},
73
+ {'metric': 'NETWORKS',
74
+ 'usage': 2.0,
75
+ 'limit': 10.0},
76
+ {'metric': 'FIREWALLS',
77
+ 'usage': 3.0,
78
+ 'limit': 10.0},
79
+ {'metric': 'IMAGES',
80
+ 'usage': 9.0,
81
+ 'limit': 10.0}]
82
+
83
+ zone_quota = [
84
+ {'metric': 'INSTANCES',
85
+ 'usage': 3.0,
86
+ 'limit': 10.0},
87
+ {'metric': 'CPUS',
88
+ 'usage': 3.0,
89
+ 'limit': 10.0},
90
+ {'metric': 'DISKS',
91
+ 'usage': 2.0,
92
+ 'limit': 10.0},
93
+ {'metric': 'DISKS_TOTAL_GB',
94
+ 'usage': 22.0,
95
+ 'limit': 25.0}]
96
+
97
+ requirements = {
98
+ 'INSTANCES': 2.0,
99
+ 'CPUS': 2.0,
100
+ 'DISKS_TOTAL_GB': 32.0,
101
+ 'SNAPSHOTS': 3.0,
102
+ 'DISKS': 3.0}
103
+
104
+ expected = {
105
+ 'INSTANCES': 7.0,
106
+ 'CPUS': -38.0,
107
+ 'DISKS_TOTAL_GB': 3.0,
108
+ 'SNAPSHOTS': 97.0,
109
+ 'DISKS': 6.0}
110
+
111
+ self.assertEqual(self.command._ExtractAvailableQuota(
112
+ project_quota, zone_quota, requirements), expected)
113
+
114
+
115
+ class MoveInstancesTest(MoveInstancesBaseTestCase):
116
+
117
+ def _CreateCommand(self):
118
+ return move_cmds.MoveInstances('moveinstances', self.flag_values)
119
+
120
+ def testServiceVersionValidation(self):
121
+ for version in command_base.SUPPORTED_VERSIONS:
122
+ if version == 'v1beta14':
123
+ break
124
+
125
+ self.flag_values.source_zone = 'src-zone'
126
+ self.flag_values.destination_zone = 'dest-zone'
127
+ self.flag_values.service_version = version
128
+ self.assertRaises(app.UsageError, self.command.Handle, ['.*'])
129
+
130
+ def testFlagValidationWithNoSourceZone(self):
131
+ self.flag_values.destination_zone = 'dest-zone'
132
+ self.flag_values.service_version = 'v1beta14'
133
+ self.assertRaises(app.UsageError, self.command.Handle, ['.*'])
134
+
135
+ def testFlagValidationWithNoDestinationZone(self):
136
+ self.flag_values.source_zone = 'src-zone'
137
+ self.flag_values.service_version = 'v1beta14'
138
+ self.assertRaises(app.UsageError, self.command.Handle, ['.*'])
139
+
140
+ def testFlagValidationWithNoSameSrcAndDest(self):
141
+ self.flag_values.source_zone = 'my-zone'
142
+ self.flag_values.destination_zone = 'my-zone'
143
+ self.assertRaises(app.UsageError, self.command.Handle, ['.*'])
144
+
145
+ def testGenerateSnapshotNames(self):
146
+ test_cases = (
147
+ [],
148
+ ['disk-0'],
149
+ ['disk-1', 'disk2', 'disk3'])
150
+
151
+ for arg in test_cases:
152
+ res = self.command._GenerateSnapshotNames(arg)
153
+ self.assertEqual(len(res), len(arg))
154
+ self.assertEqual(sorted(res.keys()), sorted(arg))
155
+ for val in res.values():
156
+ self.assertTrue(isinstance(val, basestring))
157
+ self.assertTrue(val.startswith('snapshot-'))
158
+ try:
159
+ uuid.UUID(val[len('snapshot-'):])
160
+ except ValueError:
161
+ self.fail('Value generated does not include valid UUID.')
162
+
163
+ def _GenerateInstanceResources(self, num, prefix='instance'):
164
+ template = {
165
+ 'status': 'RUNNING',
166
+ 'kind': 'compute#instance',
167
+ 'machineType': 'https://googleapis.com/compute/.../n1-standard-1',
168
+ 'zone': 'https://googleapis.com/compute/.../zones/my-zone',
169
+ 'tags': [],
170
+ 'image': 'https://googleapis.com/compute/.../images/gcel',
171
+ 'disks': [
172
+ {
173
+ 'index': 0,
174
+ 'kind': 'compute#instanceDisk',
175
+ 'type': 'EPHEMERAL',
176
+ 'mode': 'READ_WRITE'
177
+ },
178
+ {
179
+ 'index': 1,
180
+ 'kind': 'compute#attachedDisk',
181
+ 'mode': 'READ_ONLY',
182
+ 'type': 'PERSISTENT'
183
+ }
184
+ ],
185
+ 'networkInterfaces': [
186
+ {
187
+ 'networkIP': '10.211.197.175',
188
+ 'kind': 'compute#instanceNetworkInterface',
189
+ 'accessConfigs': [
190
+ {
191
+ 'type': 'ONE_TO_ONE_NAT',
192
+ 'name': 'External NAT',
193
+ 'natIP': '173.255.120.98'
194
+ }
195
+ ],
196
+ 'name': 'nic0',
197
+ 'network': 'https://googleapis.com/compute/.../networks/default'
198
+ }
199
+ ],
200
+ 'id': '12884714477555140369'}
201
+
202
+ res = []
203
+ for i in xrange(num):
204
+ instance = copy.deepcopy(template)
205
+ instance['name'] = '%s-%s' % (prefix, i)
206
+ instance['selfLink'] = (
207
+ 'https://googleapis.com/compute/.../instances/%s' % instance['name'])
208
+ instance['disks'][1]['deviceName'] = instance['name']
209
+ instance['disks'][1]['source'] = (
210
+ 'https://www.googleapis.com/compute/.../disks/%s' % instance['name'])
211
+ res.append(instance)
212
+ return res
213
+
214
+ def testCheckInstancePreconditionsWithNoMatchingInstances(self):
215
+ self.assertRaises(command_base.CommandError,
216
+ self.command._CheckInstancePreconditions,
217
+ [], [])
218
+
219
+ def testCheckInstancePreconditionsWithTooManyInstances(self):
220
+ for num_instances_to_mv in (101, 120, 200):
221
+ for num_instances_in_dest in (0, 10, 100, 101, 200):
222
+ instances_to_mv = self._GenerateInstanceResources(
223
+ num_instances_to_mv, prefix='i')
224
+ instances_in_dest = self._GenerateInstanceResources(
225
+ num_instances_in_dest, prefix='x')
226
+ self.assertRaises(
227
+ command_base.CommandError,
228
+ self.command._CheckInstancePreconditions,
229
+ instances_to_mv,
230
+ instances_in_dest)
231
+
232
+ def testCheckInstancePreconditionsWithNameCollisions(self):
233
+ # Tests with lots of collisions.
234
+ for num_instances in (1, 2, 10):
235
+ instances = self._GenerateInstanceResources(num_instances)
236
+ self.assertRaises(command_base.CommandError,
237
+ self.command._CheckInstancePreconditions,
238
+ instances, instances)
239
+
240
+ # Tests with only a single collision.
241
+ for num_instances in (1, 2, 10):
242
+ instances_to_mv = self._GenerateInstanceResources(
243
+ num_instances, prefix='i')
244
+ instances_in_dest = self._GenerateInstanceResources(
245
+ num_instances, prefix='x')
246
+ instances_in_dest.extend(self._GenerateInstanceResources(1, prefix='i'))
247
+ self.assertRaises(
248
+ command_base.CommandError,
249
+ self.command._CheckInstancePreconditions,
250
+ instances_to_mv,
251
+ instances_in_dest)
252
+
253
+ def testCheckInstancePreconditionsUnderNormalConditions(self):
254
+ for num_instances_to_mv in (1, 2, 10):
255
+ for num_instances_in_dest in (0, 2, 10):
256
+ instances_to_mv = self._GenerateInstanceResources(
257
+ num_instances_to_mv, prefix='i')
258
+ instances_in_dest = self._GenerateInstanceResources(
259
+ num_instances_in_dest, prefix='x')
260
+ self.command._CheckInstancePreconditions(
261
+ instances_to_mv, instances_in_dest)
262
+
263
+ def testCheckDiskPreconditionsWithTooManyDisks(self):
264
+ for num_disks in (101, 120, 200):
265
+ disk_names = ['disk-%s' % i for i in xrange(num_disks)]
266
+ self.assertRaises(
267
+ command_base.CommandError,
268
+ self.command._CheckDiskPreconditions,
269
+ [],
270
+ disk_names)
271
+
272
+ def testCheckDiskPreconditionsWithPoorDiskAttachment(self):
273
+ for num_instances in (1, 2, 10):
274
+ for num_disks in xrange(1, num_instances + 1):
275
+ self.assertRaises(
276
+ command_base.CommandError,
277
+ self.command._CheckDiskPreconditions,
278
+ self._GenerateInstanceResources(num_instances, prefix='i'),
279
+ ['i-%s' % i for i in xrange(num_disks)])
280
+
281
+
282
+ class ResumeMoveTest(MoveInstancesBaseTestCase):
283
+
284
+ def _CreateCommand(self):
285
+ return move_cmds.ResumeMove('resumemove', self.flag_values)
286
+
287
+ def testGetKeyWithGoodKeys(self):
288
+ test_cases = (
289
+ ({'key1': []}, 'key1', []),
290
+ ({'key1': [1, 2, 3]}, 'key1', [1, 2, 3]),
291
+ ({'key1': [1, 2, 3], 'key2': 5}, 'key2', 5))
292
+ for log, key, expected in test_cases:
293
+ self.assertEqual(self.command._GetKey(log, key), expected)
294
+
295
+ def testGetKeyWithBadKeys(self):
296
+ test_cases = (
297
+ {},
298
+ {'key1': []},
299
+ {'key1': [1, 2, 3]},
300
+ {'key1': [1, 2, 3], 'key2': 5})
301
+ for log in test_cases:
302
+ self.assertRaises(command_base.CommandError,
303
+ self.command._GetKey, log, 'nonexistent')
304
+
305
+
306
+ if __name__ == '__main__':
307
+ unittest.main()
@@ -0,0 +1,178 @@
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 VM networks."""
16
+
17
+
18
+
19
+
20
+
21
+ from google.apputils import appcommands
22
+ import gflags as flags
23
+
24
+ from gcutil import command_base
25
+
26
+
27
+ FLAGS = flags.FLAGS
28
+
29
+
30
+ class NetworkCommand(command_base.GoogleComputeCommand):
31
+ """Base command for working with the networks collection."""
32
+
33
+ default_sort_field = 'name'
34
+ summary_fields = (('name', 'name'),
35
+ ('description', 'description'),
36
+ ('addresses', 'IPv4Range'),
37
+ ('gateway', 'gatewayIPv4'))
38
+
39
+ detail_fields = (('name', 'name'),
40
+ ('description', 'description'),
41
+ ('creation-time', 'creationTimestamp'),
42
+ ('addresses', 'IPv4Range'),
43
+ ('gateway', 'gatewayIPv4'))
44
+
45
+ resource_collection_name = 'networks'
46
+
47
+ def __init__(self, name, flag_values):
48
+ super(NetworkCommand, self).__init__(name, flag_values)
49
+
50
+ def SetApi(self, api):
51
+ """Set the Google Compute Engine API for the command.
52
+
53
+ Args:
54
+ api: The Google Compute Engine API used by this command.
55
+
56
+ Returns:
57
+ None.
58
+
59
+ """
60
+ self._networks_api = api.networks()
61
+
62
+
63
+ class AddNetwork(NetworkCommand):
64
+ """Create a new network instance."""
65
+
66
+ positional_args = '<network-name>'
67
+
68
+ def __init__(self, name, flag_values):
69
+ super(AddNetwork, self).__init__(name, flag_values)
70
+
71
+ flags.DEFINE_string('description',
72
+ '',
73
+ 'Network description.',
74
+ flag_values=flag_values)
75
+ flags.DEFINE_string('range',
76
+ '10.0.0.0/8',
77
+ 'IPv4 address range of this network.',
78
+ flag_values=flag_values)
79
+ flags.DEFINE_string('gateway',
80
+ '10.0.0.1',
81
+ 'IPv4 address of the gateway within the network.',
82
+ flag_values=flag_values)
83
+ flags.DEFINE_list('reserve',
84
+ [],
85
+ 'IPv4 addresses on the network which should not be '
86
+ 'automatically assigned (comma separated).',
87
+ flag_values=flag_values)
88
+
89
+ def Handle(self, network_name):
90
+ """Add the specified network.
91
+
92
+ Args:
93
+ network_name: The name of the network to add.
94
+
95
+ Returns:
96
+ The result of adding the network.
97
+ """
98
+ network_resource = {
99
+ 'kind': self._GetResourceApiKind('network'),
100
+ 'name': self.DenormalizeResourceName(network_name),
101
+ 'description': self._flags.description,
102
+ 'IPv4Range': self._flags.range,
103
+ 'gatewayIPv4': self._flags.gateway,
104
+ 'reservedIPv4': self._flags.reserve,
105
+ }
106
+
107
+ network_request = self._networks_api.insert(project=self._project,
108
+ body=network_resource)
109
+ return network_request.execute()
110
+
111
+
112
+ class GetNetwork(NetworkCommand):
113
+ """Get a network instance."""
114
+
115
+ positional_args = '<network-name>'
116
+
117
+ def __init__(self, name, flag_values):
118
+ super(GetNetwork, self).__init__(name, flag_values)
119
+
120
+ def Handle(self, network_name):
121
+ """Get the specified network.
122
+
123
+ Args:
124
+ network_name: The name of the network to get.
125
+
126
+ Returns:
127
+ The result of getting the network.
128
+ """
129
+ network_request = self._networks_api.get(
130
+ project=self._project,
131
+ network=self.DenormalizeResourceName(network_name))
132
+
133
+ return network_request.execute()
134
+
135
+
136
+ class DeleteNetwork(NetworkCommand):
137
+ """Delete one or more machine networks.
138
+
139
+ If multiple network names are specified, the networks will be deleted in
140
+ parallel.
141
+ """
142
+
143
+ positional_args = '<network-name-1> ... <network-name-n>'
144
+ safety_prompt = 'Delete network'
145
+
146
+ def __init__(self, name, flag_values):
147
+ super(DeleteNetwork, self).__init__(name, flag_values)
148
+
149
+ def Handle(self, *network_names):
150
+ """Delete the specified networks.
151
+
152
+ Args:
153
+ *network_names: The names of the networks to delete.
154
+
155
+ Returns:
156
+ Tuple (results, exceptions) - results of deleting the networks.
157
+ """
158
+ requests = []
159
+ for name in network_names:
160
+ requests.append(self._networks_api.delete(
161
+ project=self._project,
162
+ network=self.DenormalizeResourceName(name)))
163
+ results, exceptions = self.ExecuteRequests(requests)
164
+ return self.MakeListResult(results, 'operationList'), exceptions
165
+
166
+
167
+ class ListNetworks(NetworkCommand, command_base.GoogleComputeListCommand):
168
+ """List the networks for a project."""
169
+
170
+ def ListFunc(self):
171
+ return self._networks_api.list
172
+
173
+
174
+ def AddCommands():
175
+ appcommands.AddCmd('addnetwork', AddNetwork)
176
+ appcommands.AddCmd('getnetwork', GetNetwork)
177
+ appcommands.AddCmd('deletenetwork', DeleteNetwork)
178
+ appcommands.AddCmd('listnetworks', ListNetworks)