1# -*- coding: utf-8 -*- #
2# Copyright 2018 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"""services vpc-peering helper functions."""
16
17from __future__ import absolute_import
18from __future__ import division
19from __future__ import unicode_literals
20
21from apitools.base.py import exceptions as apitools_exceptions
22from googlecloudsdk.api_lib.services import exceptions
23from googlecloudsdk.api_lib.util import apis
24
25
26def CreateConnection(project_number, service, network, ranges):
27  """Make API call to create a connection a specific service.
28
29  Args:
30    project_number: The number of the project for which to peer the service.
31    service: The name of the service to peer with.
32    network: The network in consumer project to peer with.
33    ranges: The names of IP CIDR ranges for peering service to use.
34
35  Raises:
36    exceptions.CreateConnectionsPermissionDeniedException: when the create
37        connection API fails.
38    apitools_exceptions.HttpError: Another miscellaneous error with the peering
39        service.
40
41  Returns:
42    The result of the create connection operation.
43  """
44  client = _GetClientInstance()
45  messages = client.MESSAGES_MODULE
46
47  # the API only takes project number, so we cannot use resource parser.
48  request = messages.ServicenetworkingServicesConnectionsCreateRequest(
49      parent='services/' + service,
50      connection=messages.Connection(
51          network='projects/%s/global/networks/%s' % (project_number, network),
52          reservedPeeringRanges=ranges))
53  try:
54    return client.services_connections.Create(request)
55  except (apitools_exceptions.HttpForbiddenError,
56          apitools_exceptions.HttpNotFoundError) as e:
57    exceptions.ReraiseError(
58        e, exceptions.CreateConnectionsPermissionDeniedException)
59
60
61def UpdateConnection(project_number, service, network, ranges, force):
62  """Make API call to update a connection a specific service.
63
64  Args:
65    project_number: The number of the project for which to peer the service.
66    service: The name of the service to peer with.
67    network: The network in consumer project to peer with.
68    ranges: The names of IP CIDR ranges for peering service to use.
69    force: If true, update the connection even if the update can be destructive.
70
71  Raises:
72    exceptions.CreateConnectionsPermissionDeniedException: when the create
73        connection API fails.
74    apitools_exceptions.HttpError: Another miscellaneous error with the peering
75        service.
76
77  Returns:
78    The result of the update connection operation.
79  """
80  client = _GetClientInstance()
81  messages = client.MESSAGES_MODULE
82
83  # the API only takes project number, so we cannot use resource parser.
84  request = messages.ServicenetworkingServicesConnectionsPatchRequest(
85      name='services/%s/connections/-' % service,
86      connection=messages.Connection(
87          network='projects/%s/global/networks/%s' % (project_number, network),
88          reservedPeeringRanges=ranges),
89      force=force)
90  try:
91    return client.services_connections.Patch(request)
92  except (apitools_exceptions.HttpForbiddenError,
93          apitools_exceptions.HttpNotFoundError) as e:
94    exceptions.ReraiseError(
95        e, exceptions.CreateConnectionsPermissionDeniedException)
96
97
98def ListConnections(project_number, service, network):
99  """Make API call to list connections of a network for a specific service.
100
101  Args:
102    project_number: The number of the project for which to peer the service.
103    service: The name of the service to peer with.
104    network: The network in consumer project to peer with.
105
106  Raises:
107    exceptions.ListConnectionsPermissionDeniedException: when the list
108    connections API fails.
109    apitools_exceptions.HttpError: Another miscellaneous error with the peering
110        service.
111
112  Returns:
113    The list of connections.
114  """
115  client = _GetClientInstance()
116  messages = client.MESSAGES_MODULE
117
118  # The API only takes project number, so we cannot use resource parser.
119  request = messages.ServicenetworkingServicesConnectionsListRequest(
120      parent='services/' + service,
121      network='projects/{0}/global/networks/{1}'.format(project_number,
122                                                        network))
123  try:
124    return client.services_connections.List(request).connections
125  except (apitools_exceptions.HttpForbiddenError,
126          apitools_exceptions.HttpNotFoundError) as e:
127    exceptions.ReraiseError(e,
128                            exceptions.ListConnectionsPermissionDeniedException)
129
130
131def EnableVpcServiceControls(project_number, service, network):
132  """Make API call to enable VPC service controls for a specific service.
133
134  Args:
135    project_number: The number of the project which is peered with the service.
136    service: The name of the service to enable VPC service controls for.
137    network: The network in the consumer project peered with the service.
138
139  Raises:
140    exceptions.EnableVpcServiceControlsPermissionDeniedException: when the
141    enable VPC service controls API fails.
142    apitools_exceptions.HttpError: Another miscellaneous error with the peering
143        service.
144
145  Returns:
146    The result of the enable VPC service controls operation.
147  """
148  client = _GetClientInstance()
149  messages = client.MESSAGES_MODULE
150
151  # the API only takes project number, so we cannot use resource parser.
152  request = messages.ServicenetworkingServicesEnableVpcServiceControlsRequest(
153      enableVpcServiceControlsRequest=messages.EnableVpcServiceControlsRequest(
154          consumerNetwork='projects/%s/global/networks/%s' %
155          (project_number, network)),
156      parent='services/' + service)
157  try:
158    return client.services.EnableVpcServiceControls(request)
159  except (apitools_exceptions.HttpForbiddenError,
160          apitools_exceptions.HttpNotFoundError) as e:
161    exceptions.ReraiseError(
162        e, exceptions.EnableVpcServiceControlsPermissionDeniedException)
163
164
165def DisableVpcServiceControls(project_number, service, network):
166  """Make API call to disable VPC service controls for a specific service.
167
168  Args:
169    project_number: The number of the project which is peered with the service.
170    service: The name of the service to disable VPC service controls for.
171    network: The network in the consumer project peered with the service.
172
173  Raises:
174    exceptions.DisableVpcServiceControlsPermissionDeniedException: when the
175    disable VPC service controls API fails.
176    apitools_exceptions.HttpError: Another miscellaneous error with the peering
177        service.
178
179  Returns:
180    The result of the disable VPC service controls operation.
181  """
182  client = _GetClientInstance()
183  messages = client.MESSAGES_MODULE
184
185  # the API only takes project number, so we cannot use resource parser.
186  request = messages.ServicenetworkingServicesDisableVpcServiceControlsRequest(
187      disableVpcServiceControlsRequest=messages
188      .DisableVpcServiceControlsRequest(
189          consumerNetwork='projects/%s/global/networks/%s' %
190          (project_number, network)),
191      parent='services/' + service)
192  try:
193    return client.services.DisableVpcServiceControls(request)
194  except (apitools_exceptions.HttpForbiddenError,
195          apitools_exceptions.HttpNotFoundError) as e:
196    exceptions.ReraiseError(
197        e, exceptions.DisableVpcServiceControlsPermissionDeniedException)
198
199
200def CreatePeeredDnsDomain(project_number, service, network, name, dns_suffix):
201  """Make API call to create a peered DNS domain for a specific connection.
202
203  Args:
204    project_number: The number of the project which is peered with the service.
205    service: The name of the service to create a peered DNS domain for.
206    network: The network in the consumer project peered with the service.
207    name: The name of the peered DNS domain.
208    dns_suffix: The DNS domain name suffix of the peered DNS domain.
209
210  Raises:
211    exceptions.CreatePeeredDnsDomainPermissionDeniedException: when the create
212    peered DNS domain API fails.
213    apitools_exceptions.HttpError: Another miscellaneous error with the peering
214    service.
215
216  Returns:
217    The result of the create peered DNS domain operation.
218  """
219  client = _GetClientInstance()
220  messages = client.MESSAGES_MODULE
221
222  # the API only takes project number, so we cannot use resource parser.
223  request = messages.ServicenetworkingServicesProjectsGlobalNetworksPeeredDnsDomainsCreateRequest(
224      parent='services/%s/projects/%s/global/networks/%s' %
225      (service, project_number, network),
226      peeredDnsDomain=messages.PeeredDnsDomain(dnsSuffix=dns_suffix, name=name),
227  )
228  try:
229    return client.services_projects_global_networks_peeredDnsDomains.Create(
230        request)
231  except (apitools_exceptions.HttpForbiddenError,
232          apitools_exceptions.HttpNotFoundError) as e:
233    exceptions.ReraiseError(
234        e,
235        exceptions.CreatePeeredDnsDomainPermissionDeniedException,
236    )
237
238
239def DeletePeeredDnsDomain(project_number, service, network, name):
240  """Make API call to delete a peered DNS domain for a specific connection.
241
242  Args:
243    project_number: The number of the project which is peered with the service.
244    service: The name of the service to delete a peered DNS domain for.
245    network: The network in the consumer project peered with the service.
246    name: The name of the peered DNS domain.
247
248  Raises:
249    exceptions.DeletePeeredDnsDomainPermissionDeniedException: when the delete
250    peered DNS domain API fails.
251    apitools_exceptions.HttpError: Another miscellaneous error with the peering
252    service.
253
254  Returns:
255    The result of the delete peered DNS domain operation.
256  """
257  client = _GetClientInstance()
258  messages = client.MESSAGES_MODULE
259
260  # the API only takes project number, so we cannot use resource parser.
261  request = messages.ServicenetworkingServicesProjectsGlobalNetworksPeeredDnsDomainsDeleteRequest(
262      name='services/%s/projects/%s/global/networks/%s/peeredDnsDomains/%s' %
263      (service, project_number, network, name))
264  try:
265    return client.services_projects_global_networks_peeredDnsDomains.Delete(
266        request)
267  except (apitools_exceptions.HttpForbiddenError,
268          apitools_exceptions.HttpNotFoundError) as e:
269    exceptions.ReraiseError(
270        e,
271        exceptions.DeletePeeredDnsDomainPermissionDeniedException,
272    )
273
274
275def ListPeeredDnsDomains(project_number, service, network):
276  """Make API call to list the peered DNS domains for a specific connection.
277
278  Args:
279    project_number: The number of the project which is peered with the service.
280    service: The name of the service to list the peered DNS domains for.
281    network: The network in the consumer project peered with the service.
282
283  Raises:
284    exceptions.ListPeeredDnsDomainsPermissionDeniedException: when the delete
285    peered DNS domain API fails.
286    apitools_exceptions.HttpError: Another miscellaneous error with the peering
287    service.
288
289  Returns:
290    The list of peered DNS domains.
291  """
292  client = _GetClientInstance()
293  messages = client.MESSAGES_MODULE
294
295  # the API only takes project number, so we cannot use resource parser.
296  request = messages.ServicenetworkingServicesProjectsGlobalNetworksPeeredDnsDomainsListRequest(
297      parent='services/%s/projects/%s/global/networks/%s' %
298      (service, project_number, network))
299  try:
300    return client.services_projects_global_networks_peeredDnsDomains.List(
301        request).peeredDnsDomains
302  except (apitools_exceptions.HttpForbiddenError,
303          apitools_exceptions.HttpNotFoundError) as e:
304    exceptions.ReraiseError(
305        e,
306        exceptions.ListPeeredDnsDomainsPermissionDeniedException,
307    )
308
309
310def GetOperation(name):
311  """Make API call to get an operation.
312
313  Args:
314    name: The name of operation.
315
316  Raises:
317    exceptions.OperationErrorException: when the getting operation API fails.
318    apitools_exceptions.HttpError: Another miscellaneous error with the peering
319        service.
320
321  Returns:
322    The long running operation.
323  """
324  client = _GetClientInstance()
325  messages = client.MESSAGES_MODULE
326  request = messages.ServicenetworkingOperationsGetRequest(name=name)
327  try:
328    return client.operations.Get(request)
329  except (apitools_exceptions.HttpForbiddenError,
330          apitools_exceptions.HttpNotFoundError) as e:
331    exceptions.ReraiseError(e, exceptions.OperationErrorException)
332
333
334def _GetClientInstance():
335  return apis.GetClientInstance('servicenetworking', 'v1', no_http=False)
336