1# -*- coding: utf-8 -*- #
2# Copyright 2017 Google LLC. All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#    http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16"""Compute resource completers for the core.cache.completion_cache module."""
17
18from __future__ import absolute_import
19from __future__ import division
20from __future__ import unicode_literals
21
22import os
23
24from googlecloudsdk.command_lib.resource_manager import completers as resource_manager_completers
25from googlecloudsdk.command_lib.util import completers
26from googlecloudsdk.command_lib.util import parameter_info_lib
27from googlecloudsdk.core import exceptions
28from googlecloudsdk.core.util import encoding
29
30
31class Error(exceptions.Error):
32  """Exceptions for this module."""
33
34
35class TestParametersRequired(Error):
36  """Test parameters must be exported in _ARGCOMPLETE_TEST."""
37
38
39# resource param project aggregators
40
41
42class ResourceParamCompleter(completers.ResourceParamCompleter):
43
44  def ParameterInfo(self, parsed_args, argument):
45    return parameter_info_lib.ParameterInfoByConvention(
46        parsed_args,
47        argument,
48        self.collection,
49        updaters={
50            'project': (resource_manager_completers.ProjectCompleter, True),
51        },
52    )
53
54
55# common parameter completers
56
57
58class RegionsCompleter(ResourceParamCompleter):
59  """The region completer."""
60
61  def __init__(self, **kwargs):
62    super(RegionsCompleter, self).__init__(
63        collection='compute.regions',
64        list_command='compute regions list --uri',
65        param='region',
66        timeout=8*60*60,
67        **kwargs)
68
69
70class ZonesCompleter(ResourceParamCompleter):
71  """The zone completer."""
72
73  def __init__(self, **kwargs):
74    super(ZonesCompleter, self).__init__(
75        collection='compute.zones',
76        list_command='compute zones list --uri',
77        param='zone',
78        timeout=8*60*60,
79        **kwargs)
80
81
82# completers by parameter name convention
83
84
85COMPLETERS_BY_CONVENTION = {
86    'project': (resource_manager_completers.ProjectCompleter, True),
87    'region': (RegionsCompleter, False),
88    'zone': (ZonesCompleter, False),
89}
90
91
92# list command project aggregators
93
94
95class ListCommandParameterInfo(parameter_info_lib.ParameterInfoByConvention):
96
97  def GetFlag(self, parameter_name, parameter_value=None,
98              check_properties=True, for_update=False):
99    if for_update and self.GetDest(parameter_name) in ('region', 'zone'):
100      return None
101    return super(ListCommandParameterInfo, self).GetFlag(
102        parameter_name,
103        parameter_value=parameter_value,
104        check_properties=check_properties,
105        for_update=for_update,
106    )
107
108
109class ListCommandCompleter(completers.ListCommandCompleter):
110
111  def ParameterInfo(self, parsed_args, argument):
112    return ListCommandParameterInfo(
113        parsed_args,
114        argument,
115        self.collection,
116        updaters=COMPLETERS_BY_CONVENTION,
117    )
118
119
120class GlobalListCommandCompleter(ListCommandCompleter):
121  """A global resource list command completer."""
122
123  def ParameterInfo(self, parsed_args, argument):
124    return ListCommandParameterInfo(
125        parsed_args,
126        argument,
127        self.collection,
128        additional_params=['global'],
129        updaters=COMPLETERS_BY_CONVENTION,
130    )
131
132
133# completers referenced by multiple command groups and/or flags modules
134#
135# Search*Completer ResourceSearchCompleters have ListCommandCompleter
136# variants that are currently the default.  The Search completers are currently
137# for testing only.
138
139
140class DisksCompleter(ListCommandCompleter):
141
142  def __init__(self, **kwargs):
143    super(DisksCompleter, self).__init__(
144        collection='compute.disks',
145        list_command='compute disks list --uri',
146        **kwargs)
147
148
149class DiskTypesRegionalCompleter(ListCommandCompleter):
150
151  def __init__(self, **kwargs):
152    super(DiskTypesRegionalCompleter, self).__init__(
153        collection='compute.regionDiskTypes',
154        api_version='alpha',
155        list_command='alpha compute disk-types list --uri --filter=-zone:*',
156        **kwargs)
157
158
159class DiskTypesZonalCompleter(ListCommandCompleter):
160
161  def __init__(self, **kwargs):
162    super(DiskTypesZonalCompleter, self).__init__(
163        collection='compute.diskTypes',
164        api_version='alpha',
165        list_command='alpha compute disk-types list --uri --filter=zone:*',
166        **kwargs)
167
168
169class DiskTypesCompleter(completers.MultiResourceCompleter):
170
171  def __init__(self, **kwargs):
172    super(DiskTypesCompleter, self).__init__(
173        completers=[DiskTypesRegionalCompleter, DiskTypesZonalCompleter],
174        **kwargs)
175
176
177class HealthChecksCompleter(ListCommandCompleter):
178
179  def __init__(self, **kwargs):
180    super(HealthChecksCompleter, self).__init__(
181        collection='compute.healthChecks',
182        list_command='compute health-checks list --uri',
183        **kwargs)
184
185
186class HealthChecksCompleterAlpha(completers.MultiResourceCompleter):
187
188  def __init__(self, **kwargs):
189    super(HealthChecksCompleterAlpha, self).__init__(
190        completers=[GlobalHealthChecksCompleter, RegionHealthChecksCompleter],
191        **kwargs)
192
193
194class GlobalHealthChecksCompleter(ListCommandCompleter):
195
196  def __init__(self, **kwargs):
197    super(GlobalHealthChecksCompleter, self).__init__(
198        collection='compute.healthChecks',
199        api_version='alpha',
200        list_command='alpha compute health-checks list --global --uri',
201        **kwargs)
202
203
204class RegionHealthChecksCompleter(ListCommandCompleter):
205
206  def __init__(self, **kwargs):
207    super(RegionHealthChecksCompleter, self).__init__(
208        collection='compute.regionHealthChecks',
209        api_version='alpha',
210        list_command='alpha compute health-checks list --filter=region:* --uri',
211        **kwargs)
212
213
214class SearchHealthChecksCompleter(completers.ResourceSearchCompleter):
215
216  def __init__(self, **kwargs):
217    super(SearchHealthChecksCompleter, self).__init__(
218        collection='compute.healthChecks',
219        **kwargs)
220
221
222class HttpHealthChecksCompleter(ListCommandCompleter):
223
224  def __init__(self, **kwargs):
225    super(HttpHealthChecksCompleter, self).__init__(
226        collection='compute.httpHealthChecks',
227        list_command='compute http-health-checks list --uri',
228        **kwargs)
229
230
231class SearchHttpHealthChecksCompleter(completers.ResourceSearchCompleter):
232
233  def __init__(self, **kwargs):
234    super(SearchHttpHealthChecksCompleter, self).__init__(
235        collection='compute.httpHealthChecks',
236        **kwargs)
237
238
239class HttpsHealthChecksCompleter(ListCommandCompleter):
240
241  def __init__(self, **kwargs):
242    super(HttpsHealthChecksCompleter, self).__init__(
243        collection='compute.httpsHealthChecks',
244        list_command='compute https-health-checks list --uri',
245        **kwargs)
246
247
248class SearchHttpsHealthChecksCompleter(completers.ResourceSearchCompleter):
249
250  def __init__(self, **kwargs):
251    super(SearchHttpsHealthChecksCompleter, self).__init__(
252        collection='compute.httpsHealthChecks',
253        **kwargs)
254
255
256class InstancesCompleter(ListCommandCompleter):
257
258  def __init__(self, **kwargs):
259    super(InstancesCompleter, self).__init__(
260        collection='compute.instances',
261        list_command='compute instances list --uri',
262        **kwargs)
263
264
265class SearchInstancesCompleter(completers.ResourceSearchCompleter):
266
267  def __init__(self, **kwargs):
268    super(SearchInstancesCompleter, self).__init__(
269        collection='compute.instances',
270        **kwargs)
271
272
273class InstanceGroupsCompleter(ListCommandCompleter):
274
275  def __init__(self, **kwargs):
276    super(InstanceGroupsCompleter, self).__init__(
277        collection='compute.instanceGroups',
278        list_command='compute instance-groups unmanaged list --uri',
279        **kwargs)
280
281
282class InstanceTemplatesCompleter(ListCommandCompleter):
283
284  def __init__(self, **kwargs):
285    super(InstanceTemplatesCompleter, self).__init__(
286        collection='compute.instanceTemplates',
287        list_command='compute instance-templates list --uri',
288        **kwargs)
289
290
291class SearchInstanceTemplatesCompleter(completers.ResourceSearchCompleter):
292
293  def __init__(self, **kwargs):
294    super(SearchInstanceTemplatesCompleter, self).__init__(
295        collection='compute.instanceTemplates',
296        **kwargs)
297
298
299class MachineImagesCompleter(ListCommandCompleter):
300
301  def __init__(self, **kwargs):
302    super(MachineImagesCompleter, self).__init__(
303        collection='compute.machineImages',
304        list_command='beta compute machine-images list --uri',
305        api_version='beta',
306        **kwargs)
307
308
309class SearchMachineImagesCompleter(completers.ResourceSearchCompleter):
310
311  def __init__(self, **kwargs):
312    super(SearchMachineImagesCompleter, self).__init__(
313        collection='compute.machineImages',
314        api_version='alpha',
315        **kwargs)
316
317
318class InstantSnapshotsCompleter(completers.MultiResourceCompleter):
319
320  def __init__(self, **kwargs):
321    super(InstantSnapshotsCompleter, self).__init__(
322        completers=[
323            RegionInstantSnapshotsCompleter, ZoneInstantSnapshotsCompleter
324        ],
325        **kwargs)
326
327
328class ZoneInstantSnapshotsCompleter(ListCommandCompleter):
329
330  def __init__(self, **kwargs):
331    super(ZoneInstantSnapshotsCompleter, self).__init__(
332        collection='compute.zoneInstantSnapshots',
333        list_command='alpha compute instant-snapshots list --uri',
334        api_version='alpha',
335        **kwargs)
336
337
338class RegionInstantSnapshotsCompleter(ListCommandCompleter):
339
340  def __init__(self, **kwargs):
341    super(RegionInstantSnapshotsCompleter, self).__init__(
342        collection='compute.regionInstantSnapshots',
343        list_command='alpha compute instant-snapshots list --uri',
344        api_version='alpha',
345        **kwargs)
346
347
348class MachineTypesCompleter(ListCommandCompleter):
349
350  def __init__(self, **kwargs):
351    super(MachineTypesCompleter, self).__init__(
352        collection='compute.machineTypes',
353        list_command='compute machine-types list --uri',
354        **kwargs)
355
356
357class RoutesCompleter(ListCommandCompleter):
358
359  def __init__(self, **kwargs):
360    super(RoutesCompleter, self).__init__(
361        collection='compute.routes',
362        list_command='compute routes list --uri',
363        **kwargs)
364
365
366# completers for testing the completer framework
367
368
369class TestCompleter(ListCommandCompleter):
370  """A completer that checks env var _ARGCOMPLETE_TEST for completer info.
371
372  For testing list command completers.
373
374  The env var is a comma separated list of name=value items:
375    collection=COLLECTION
376      The collection name.
377    list_command=COMMAND
378      The gcloud list command string with gcloud omitted.
379  """
380
381  def __init__(self, **kwargs):
382    test_parameters = encoding.GetEncodedValue(os.environ, '_ARGCOMPLETE_TEST',
383                                               'parameters=bad')
384    kwargs = dict(kwargs)
385    for pair in test_parameters.split(','):
386      name, value = pair.split('=')
387      kwargs[name] = value
388    if 'collection' not in kwargs or 'list_command' not in kwargs:
389      raise TestParametersRequired(
390          'Specify test completer parameters in the _ARGCOMPLETE_TEST '
391          'environment variable. It is a comma-separated separated list of '
392          'name=value test parameters and must contain at least '
393          '"collection=COLLECTION,list_command=LIST COMMAND" parameters.')
394    super(TestCompleter, self).__init__(**kwargs)
395