1# -*- coding: utf-8 -*- #
2# Copyright 2019 Google Inc. 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"""Organization Security policy."""
16
17from __future__ import absolute_import
18from __future__ import division
19from __future__ import unicode_literals
20
21from googlecloudsdk.api_lib.compute.operations import poller
22from googlecloudsdk.api_lib.util import waiter
23
24OP_COLLECTION_NAME = 'compute.globalOrganizationOperations'
25API_COLLECTION_NAME = 'compute.organizationSecurityPolicies'
26
27
28class DeletePoller(poller.Poller):
29
30  def GetResult(self, operation):
31    # For delete operations, once the operation status is DONE, there is
32    # nothing further to fetch.
33    return
34
35
36class OrgSecurityPolicy(object):
37  """Abstracts Organization SecurityPolicy resource."""
38
39  def __init__(self,
40               ref=None,
41               compute_client=None,
42               resources=None,
43               version='beta'):
44    self.ref = ref
45    self._compute_client = compute_client
46    self._resources = resources
47    self._version = version
48    self._op_has_project = self._HasProject(OP_COLLECTION_NAME)
49    self._api_has_project = self._HasProject(API_COLLECTION_NAME)
50
51  def _HasProject(self, collection):
52    collection_info = self._resources.GetCollectionInfo(collection,
53                                                        self._version)
54    return 'projects' in collection_info.path or 'projects' in collection_info.base_url
55
56  @property
57  def _client(self):
58    return self._compute_client.apitools_client
59
60  @property
61  def _messages(self):
62    return self._compute_client.messages
63
64  @property
65  def _service(self):
66    return self._client.organizationSecurityPolicies
67
68  def _MakeAddAssociationRequestTuple(self, association, security_policy_id,
69                                      replace_existing_association):
70    return (
71        self._client.organizationSecurityPolicies, 'AddAssociation',
72        self._messages.ComputeOrganizationSecurityPoliciesAddAssociationRequest(
73            securityPolicyAssociation=association,
74            securityPolicy=security_policy_id,
75            replaceExistingAssociation=replace_existing_association))
76
77  def _MakeDeleteAssociationRequestTuple(self, security_policy_id):
78    return (self._client.organizationSecurityPolicies, 'RemoveAssociation',
79            self._messages
80            .ComputeOrganizationSecurityPoliciesRemoveAssociationRequest(
81                name=self.ref.Name(), securityPolicy=security_policy_id))
82
83  def _MakeListAssociationsRequestTuple(self, target_resource):
84    return (self._client.organizationSecurityPolicies, 'ListAssociations',
85            self._messages
86            .ComputeOrganizationSecurityPoliciesListAssociationsRequest(
87                targetResource=target_resource))
88
89  def _MakeDeleteRequestTuple(self, sp_id=None):
90    return (self._client.organizationSecurityPolicies, 'Delete',
91            self._messages.ComputeOrganizationSecurityPoliciesDeleteRequest(
92                securityPolicy=sp_id))
93
94  def _MakeUpdateRequestTuple(self, sp_id=None, security_policy=None):
95    if sp_id:
96      return (self._client.organizationSecurityPolicies, 'Patch',
97              self._messages.ComputeOrganizationSecurityPoliciesPatchRequest(
98                  securityPolicy=sp_id, securityPolicyResource=security_policy))
99    return (self._client.organizationSecurityPolicies, 'Patch',
100            self._messages.ComputeOrganizationSecurityPoliciesPatchRequest(
101                securityPolicy=self.ref.Name(),
102                securityPolicyResource=security_policy))
103
104  def _MakeDescribeRequestTuple(self, sp_id=None):
105    if sp_id:
106      return (self._client.organizationSecurityPolicies, 'Get',
107              self._messages.ComputeOrganizationSecurityPoliciesGetRequest(
108                  securityPolicy=sp_id))
109    return (self._client.organizationSecurityPolicies, 'Get',
110            self._messages.ComputeOrganizationSecurityPoliciesGetRequest(
111                securityPolicy=self.ref.Name()))
112
113  def _MakeMoveRequestTuple(self, sp_id=None, parent_id=None):
114    return (self._client.organizationSecurityPolicies, 'Move',
115            self._messages.ComputeOrganizationSecurityPoliciesMoveRequest(
116                securityPolicy=sp_id, parentId=parent_id))
117
118  def _MakeCopyRulesRequestTuple(self,
119                                 dest_sp_id=None,
120                                 source_security_policy=None):
121    return (self._client.organizationSecurityPolicies, 'CopyRules',
122            self._messages.ComputeOrganizationSecurityPoliciesCopyRulesRequest(
123                securityPolicy=dest_sp_id,
124                sourceSecurityPolicy=source_security_policy))
125
126  def _MakeListRequestTuple(self, parent_id):
127    return (self._client.organizationSecurityPolicies, 'List',
128            self._messages.ComputeOrganizationSecurityPoliciesListRequest(
129                parentId=parent_id))
130
131  def _MakeCreateRequestTuple(self, security_policy, parent_id):
132    return (self._client.organizationSecurityPolicies, 'Insert',
133            self._messages.ComputeOrganizationSecurityPoliciesInsertRequest(
134                parentId=parent_id, securityPolicy=security_policy))
135
136  def AddAssociation(self,
137                     association=None,
138                     security_policy_id=None,
139                     replace_existing_association=False,
140                     batch_mode=False,
141                     only_generate_request=False):
142    """Sends request to add an association."""
143
144    if batch_mode:
145      requests = [
146          self._MakeAddAssociationRequestTuple(association, security_policy_id,
147                                               replace_existing_association)
148      ]
149      if not only_generate_request:
150        return self._compute_client.MakeRequests(requests)
151      return requests
152
153    op_res = self._service.AddAssociation(
154        self._MakeAddAssociationRequestTuple(association, security_policy_id,
155                                             replace_existing_association)[2])
156    return self.WaitOperation(
157        op_res, message='Add association of the organization Security Policy.')
158
159  def DeleteAssociation(self,
160                        security_policy_id=None,
161                        batch_mode=False,
162                        only_generate_request=False):
163    """Sends request to delete an association."""
164
165    if batch_mode:
166      requests = [self._MakeDeleteAssociationRequestTuple(security_policy_id)]
167      if not only_generate_request:
168        return self._compute_client.MakeRequests(requests)
169      return requests
170
171    op_res = self._service.RemoveAssociation(
172        self._MakeDeleteAssociationRequestTuple(security_policy_id)[2])
173    return self.WaitOperation(
174        op_res,
175        message='Delete association of the organization Security Policy.')
176
177  def ListAssociations(self,
178                       target_resource=None,
179                       batch_mode=False,
180                       only_generate_request=False):
181    """Sends request to list all the associations."""
182
183    if batch_mode:
184      requests = [self._MakeListAssociationsRequestTuple(target_resource)]
185      if not only_generate_request:
186        return self._compute_client.MakeRequests(requests)
187      return requests
188
189    return [
190        self._service.ListAssociations(
191            self._MakeListAssociationsRequestTuple(target_resource)[2])
192    ]
193
194  def Delete(self, sp_id=None, batch_mode=False, only_generate_request=False):
195    """Sends request to delete a security policy."""
196
197    if batch_mode:
198      requests = [self._MakeDeleteRequestTuple(sp_id=sp_id)]
199      if not only_generate_request:
200        return self._compute_client.MakeRequests(requests)
201      return requests
202
203    op_res = self._service.Delete(self._MakeDeleteRequestTuple(sp_id=sp_id)[2])
204    operation_poller = DeletePoller(self._service, self.ref)
205    return self.WaitOperation(
206        op_res,
207        operation_poller=operation_poller,
208        message='Delete the organization Security Policy.')
209
210  def WaitOperation(self, operation, operation_poller=None, message=None):
211    if not operation_poller:
212      operation_poller = poller.Poller(
213          self._service, self.ref, has_project=self._api_has_project)
214    if self._op_has_project and 'projects' not in operation.selfLink:
215      operation.selfLink = operation.selfLink.replace('locations',
216                                                      'projects/locations')
217    operation_ref = self._resources.Parse(
218        operation.selfLink, collection=OP_COLLECTION_NAME)
219    return waiter.WaitFor(operation_poller, operation_ref, message)
220
221  def Update(self,
222             sp_id=None,
223             only_generate_request=False,
224             security_policy=None,
225             batch_mode=False):
226    """Sends request to update a security policy."""
227
228    if batch_mode:
229      requests = [
230          self._MakeUpdateRequestTuple(
231              sp_id=sp_id, security_policy=security_policy)
232      ]
233      if not only_generate_request:
234        return self._compute_client.MakeRequests(requests)
235      return requests
236
237    op_res = self._service.Patch(
238        self._MakeUpdateRequestTuple(
239            sp_id=sp_id, security_policy=security_policy)[2])
240    return self.WaitOperation(
241        op_res, message='Update the organization Security Policy.')
242
243  def Move(self,
244           only_generate_request=False,
245           sp_id=None,
246           parent_id=None,
247           batch_mode=False):
248    """Sends request to move the security policy to anther parent."""
249    if batch_mode:
250      requests = [self._MakeMoveRequestTuple(sp_id=sp_id, parent_id=parent_id)]
251      if not only_generate_request:
252        return self._compute_client.MakeRequests(requests)
253      return requests
254
255    op_res = self._service.Move(
256        self._MakeMoveRequestTuple(sp_id=sp_id, parent_id=parent_id)[2])
257    return self.WaitOperation(
258        op_res, message='Move the organization Security Policy.')
259
260  def CopyRules(self,
261                only_generate_request=False,
262                dest_sp_id=None,
263                source_security_policy=None,
264                batch_mode=False):
265    """Sends request to copy all the rules from another security policy."""
266
267    if batch_mode:
268      requests = [
269          self._MakeCopyRulesRequestTuple(
270              dest_sp_id=dest_sp_id,
271              source_security_policy=source_security_policy)
272      ]
273      if not only_generate_request:
274        return self._compute_client.MakeRequests(requests)
275      return requests
276
277    op_res = self._service.CopyRules(
278        self._MakeCopyRulesRequestTuple(
279            dest_sp_id=dest_sp_id,
280            source_security_policy=source_security_policy)[2])
281    return self.WaitOperation(
282        op_res, message='Copy rules for the organization Security Policy.')
283
284  def Describe(self, sp_id=None, batch_mode=False, only_generate_request=False):
285    """Sends request to describe a security policy."""
286
287    if batch_mode:
288      requests = [self._MakeDescribeRequestTuple(sp_id=sp_id)]
289      if not only_generate_request:
290        return self._compute_client.MakeRequests(requests)
291      return requests
292
293    return [self._service.Get(self._MakeDescribeRequestTuple(sp_id=sp_id)[2])]
294
295  def List(self, parent_id=None, batch_mode=False, only_generate_request=False):
296    """Sends request to list all the security policies."""
297
298    if batch_mode:
299      requests = [self._MakeListRequestTuple(parent_id)]
300      if not only_generate_request:
301        return self._compute_client.MakeRequests(requests)
302      return requests
303
304    return [self._service.List(self._MakeListRequestTuple(parent_id)[2])]
305
306  def Create(self,
307             security_policy=None,
308             parent_id=None,
309             batch_mode=False,
310             only_generate_request=False):
311    """Sends request to create a security policy."""
312
313    if batch_mode:
314      requests = [self._MakeCreateRequestTuple(security_policy, parent_id)]
315      if not only_generate_request:
316        return self._compute_client.MakeRequests(requests)
317      return requests
318
319    op_res = self._service.Insert(
320        self._MakeCreateRequestTuple(security_policy, parent_id)[2])
321    return self.WaitOperation(
322        op_res, message='Create the organization Security Policy.')
323
324
325class OrgSecurityPolicyRule(OrgSecurityPolicy):
326  """Abstracts Organization SecurityPolicy Rule."""
327
328  def __init__(self,
329               ref=None,
330               compute_client=None,
331               resources=None,
332               version='beta'):
333    super(OrgSecurityPolicyRule, self).__init__(
334        ref=ref,
335        compute_client=compute_client,
336        resources=resources,
337        version=version)
338
339  def _MakeCreateRuleRequestTuple(self,
340                                  security_policy=None,
341                                  security_policy_rule=None):
342    return (self._client.organizationSecurityPolicies, 'AddRule',
343            self._messages.ComputeOrganizationSecurityPoliciesAddRuleRequest(
344                securityPolicy=security_policy,
345                securityPolicyRule=security_policy_rule))
346
347  def _MakeDeleteRuleRequestTuple(self, priority=None, security_policy=None):
348    return (self._client.organizationSecurityPolicies, 'RemoveRule',
349            self._messages.ComputeOrganizationSecurityPoliciesRemoveRuleRequest(
350                securityPolicy=security_policy, priority=priority))
351
352  def _MakeDescribeRuleRequestTuple(self, priority=None, security_policy=None):
353    return (self._client.organizationSecurityPolicies, 'GetRule',
354            self._messages.ComputeOrganizationSecurityPoliciesGetRuleRequest(
355                securityPolicy=security_policy, priority=priority))
356
357  def _MakeUpdateRuleRequestTuple(self,
358                                  priority=None,
359                                  security_policy=None,
360                                  security_policy_rule=None):
361    return (self._client.organizationSecurityPolicies, 'PatchRule',
362            self._messages.ComputeOrganizationSecurityPoliciesPatchRuleRequest(
363                priority=priority,
364                securityPolicy=security_policy,
365                securityPolicyRule=security_policy_rule))
366
367  def Create(self,
368             security_policy=None,
369             security_policy_rule=None,
370             batch_mode=False,
371             only_generate_request=False):
372    """Sends request to create a security policy rule."""
373
374    if batch_mode:
375      requests = [
376          self._MakeCreateRuleRequestTuple(
377              security_policy=security_policy,
378              security_policy_rule=security_policy_rule)
379      ]
380      if not only_generate_request:
381        return self._compute_client.MakeRequests(requests)
382      return requests
383
384    op_res = self._service.AddRule(
385        self._MakeCreateRuleRequestTuple(
386            security_policy=security_policy,
387            security_policy_rule=security_policy_rule)[2])
388    return self.WaitOperation(
389        op_res, message='Add a rule of the organization Security Policy.')
390
391  def Delete(self,
392             priority=None,
393             security_policy_id=None,
394             batch_mode=False,
395             only_generate_request=False):
396    """Sends request to delete a security policy rule."""
397
398    if batch_mode:
399      requests = [
400          self._MakeDeleteRuleRequestTuple(
401              priority=priority, security_policy=security_policy_id)
402      ]
403      if not only_generate_request:
404        return self._compute_client.MakeRequests(requests)
405      return requests
406
407    op_res = self._service.RemoveRule(
408        self._MakeDeleteRuleRequestTuple(
409            priority=priority, security_policy=security_policy_id)[2])
410    return self.WaitOperation(
411        op_res, message='Delete a rule of the organization Security Policy.')
412
413  def Describe(self,
414               priority=None,
415               security_policy_id=None,
416               batch_mode=False,
417               only_generate_request=False):
418    """Sends request to describe a security policy rule."""
419
420    if batch_mode:
421      requests = [
422          self._MakeDescribeRuleRequestTuple(
423              priority=priority, security_policy=security_policy_id)
424      ]
425      if not only_generate_request:
426        return self._compute_client.MakeRequests(requests)
427      return requests
428
429    return self._service.GetRule(
430        self._MakeDescribeRuleRequestTuple(
431            priority=priority, security_policy=security_policy_id)[2])
432
433  def Update(self,
434             priority=None,
435             security_policy=None,
436             security_policy_rule=None,
437             batch_mode=False,
438             only_generate_request=False):
439    """Sends request to update a security policy rule."""
440
441    if batch_mode:
442      requests = [
443          self._MakeUpdateRuleRequestTuple(
444              priority=priority,
445              security_policy=security_policy,
446              security_policy_rule=security_policy_rule)
447      ]
448      if not only_generate_request:
449        return self._compute_client.MakeRequests(requests)
450      return requests
451
452    op_res = self._service.PatchRule(
453        self._MakeUpdateRuleRequestTuple(
454            priority=priority,
455            security_policy=security_policy,
456            security_policy_rule=security_policy_rule)[2])
457    return self.WaitOperation(
458        op_res, message='Update a rule of the organization Security Policy.')
459