767 lines
24 KiB
Python
767 lines
24 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2019 Google LLC. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""Util for iap."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
import abc
|
|
|
|
from apitools.base.py import encoding
|
|
from apitools.base.py import list_pager
|
|
|
|
from googlecloudsdk.api_lib.app import appengine_api_client
|
|
from googlecloudsdk.api_lib.app import operations_util
|
|
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
|
|
from googlecloudsdk.api_lib.compute import base_classes
|
|
from googlecloudsdk.api_lib.util import apis
|
|
from googlecloudsdk.calliope import base
|
|
from googlecloudsdk.calliope import exceptions as calliope_exceptions
|
|
from googlecloudsdk.command_lib.iam import iam_util
|
|
from googlecloudsdk.command_lib.projects import util as projects_util
|
|
from googlecloudsdk.core import log
|
|
from googlecloudsdk.core import resources
|
|
from googlecloudsdk.core import yaml
|
|
import six
|
|
|
|
IAP_API = 'iap'
|
|
|
|
APPENGINE_APPS_COLLECTION = 'appengine.apps'
|
|
COMPUTE_BACKEND_SERVICES_COLLECTION = 'compute.backendServices'
|
|
COMPUTE_REGION_BACKEND_SERVICES_COLLECTION = 'compute.regionBackendServices'
|
|
PROJECTS_COLLECTION = 'iap.projects'
|
|
IAP_WEB_COLLECTION = 'iap.projects.iap_web'
|
|
IAP_WEB_SERVICES_COLLECTION = 'iap.projects.iap_web.services'
|
|
IAP_WEB_SERVICES_VERSIONS_COLLECTION = 'iap.projects.iap_web.services.versions'
|
|
IAP_TCP_DESTGROUP_COLLECTION = 'iap.projects.iap_tunnel.locations.destGroups'
|
|
IAP_TCP_LOCATIONS_COLLECTION = 'iap.projects.iap_tunnel.locations'
|
|
|
|
|
|
def _ApiVersion(release_track):
|
|
del release_track
|
|
return 'v1'
|
|
|
|
|
|
def _GetRegistry(api_version):
|
|
# Override the default API map version so we can increment API versions on a
|
|
# API interface basis.
|
|
registry = resources.REGISTRY.Clone()
|
|
registry.RegisterApiByName(IAP_API, api_version)
|
|
return registry
|
|
|
|
|
|
def _GetProject(project_id):
|
|
return projects_api.Get(projects_util.ParseProject(project_id))
|
|
|
|
|
|
class IapIamResource(six.with_metaclass(abc.ABCMeta, object)):
|
|
"""Base class for IAP IAM resources."""
|
|
|
|
def __init__(self, release_track, project):
|
|
"""Base Constructor for an IAP IAM resource.
|
|
|
|
Args:
|
|
release_track: base.ReleaseTrack, release track of command.
|
|
project: Project of the IAP IAM resource
|
|
"""
|
|
self.release_track = release_track
|
|
self.api_version = _ApiVersion(release_track)
|
|
|
|
self.client = apis.GetClientInstance(IAP_API, self.api_version)
|
|
self.registry = _GetRegistry(self.api_version)
|
|
self.project = project
|
|
|
|
@property
|
|
def messages(self):
|
|
return self.client.MESSAGES_MODULE
|
|
|
|
@property
|
|
def service(self):
|
|
return getattr(self.client, self.api_version)
|
|
|
|
@abc.abstractmethod
|
|
def _Name(self):
|
|
"""Human-readable name of the resource."""
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def _Parse(self):
|
|
"""Parses the IAP IAM resource from the arguments."""
|
|
pass
|
|
|
|
def _GetIamPolicy(self, resource_ref):
|
|
request = self.messages.IapGetIamPolicyRequest(
|
|
resource=resource_ref.RelativeName(),
|
|
getIamPolicyRequest=self.messages.GetIamPolicyRequest(
|
|
options=self.messages.GetPolicyOptions(
|
|
requestedPolicyVersion=
|
|
iam_util.MAX_LIBRARY_IAM_SUPPORTED_VERSION)))
|
|
return self.service.GetIamPolicy(request)
|
|
|
|
def GetIamPolicy(self):
|
|
"""Get IAM policy for an IAP IAM resource."""
|
|
resource_ref = self._Parse()
|
|
return self._GetIamPolicy(resource_ref)
|
|
|
|
def _SetIamPolicy(self, resource_ref, policy):
|
|
policy.version = iam_util.MAX_LIBRARY_IAM_SUPPORTED_VERSION
|
|
request = self.messages.IapSetIamPolicyRequest(
|
|
resource=resource_ref.RelativeName(),
|
|
setIamPolicyRequest=self.messages.SetIamPolicyRequest(policy=policy)
|
|
)
|
|
response = self.service.SetIamPolicy(request)
|
|
iam_util.LogSetIamPolicy(resource_ref.RelativeName(), self._Name())
|
|
return response
|
|
|
|
def SetIamPolicy(self, policy_file):
|
|
"""Set the IAM policy for an IAP IAM resource."""
|
|
policy = iam_util.ParsePolicyFile(policy_file, self.messages.Policy)
|
|
resource_ref = self._Parse()
|
|
return self._SetIamPolicy(resource_ref, policy)
|
|
|
|
def AddIamPolicyBinding(self, member, role, condition):
|
|
"""Add IAM policy binding to an IAP IAM resource."""
|
|
resource_ref = self._Parse()
|
|
|
|
policy = self._GetIamPolicy(resource_ref)
|
|
iam_util.AddBindingToIamPolicyWithCondition(
|
|
self.messages.Binding, self.messages.Expr, policy, member,
|
|
role, condition)
|
|
self._SetIamPolicy(resource_ref, policy)
|
|
|
|
def RemoveIamPolicyBinding(self, member, role, condition, all_conditions):
|
|
"""Remove IAM policy binding from an IAP IAM resource."""
|
|
resource_ref = self._Parse()
|
|
|
|
policy = self._GetIamPolicy(resource_ref)
|
|
iam_util.RemoveBindingFromIamPolicyWithCondition(
|
|
policy, member, role, condition, all_conditions=all_conditions)
|
|
self._SetIamPolicy(resource_ref, policy)
|
|
|
|
|
|
class IAPWeb(IapIamResource):
|
|
"""IAP IAM project resource.
|
|
"""
|
|
|
|
def _Name(self):
|
|
return 'project'
|
|
|
|
def _Parse(self):
|
|
project = _GetProject(self.project)
|
|
return self.registry.Parse(
|
|
None, params={
|
|
'projectsId': '{}/iap_web'.format(project.projectNumber),
|
|
}, collection=PROJECTS_COLLECTION)
|
|
|
|
|
|
def _AppEngineAppId(app_id):
|
|
return 'appengine-{}'.format(app_id)
|
|
|
|
|
|
def _GetApplication(project):
|
|
"""Returns the application, given a project."""
|
|
api_client = appengine_api_client.AppengineApiClient.GetApiClient()
|
|
application = resources.REGISTRY.Parse(
|
|
None,
|
|
params={
|
|
'appsId': project,
|
|
},
|
|
collection=APPENGINE_APPS_COLLECTION)
|
|
|
|
request = api_client.messages.AppengineAppsGetRequest(
|
|
name=application.RelativeName())
|
|
return api_client.client.apps.Get(request)
|
|
|
|
|
|
class AppEngineApplication(IapIamResource):
|
|
"""IAP IAM App Engine application resource.
|
|
"""
|
|
|
|
def _Name(self):
|
|
return 'App Engine application'
|
|
|
|
def _Parse(self):
|
|
project = _GetProject(self.project)
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'project': project.projectNumber,
|
|
'iapWebId': _AppEngineAppId(project.projectId),
|
|
},
|
|
collection=IAP_WEB_COLLECTION)
|
|
|
|
def _SetAppEngineApplicationIap(self, enabled, oauth2_client_id=None,
|
|
oauth2_client_secret=None):
|
|
application = _GetApplication(self.project)
|
|
|
|
api_client = appengine_api_client.AppengineApiClient.GetApiClient()
|
|
|
|
iap_kwargs = _MakeIAPKwargs(False, application.iap, enabled,
|
|
oauth2_client_id, oauth2_client_secret)
|
|
application_update = api_client.messages.Application(
|
|
iap=api_client.messages.IdentityAwareProxy(**iap_kwargs))
|
|
|
|
application = resources.REGISTRY.Parse(
|
|
self.project, collection=APPENGINE_APPS_COLLECTION)
|
|
|
|
update_request = api_client.messages.AppengineAppsPatchRequest(
|
|
name=application.RelativeName(),
|
|
application=application_update,
|
|
updateMask='iap,')
|
|
operation = api_client.client.apps.Patch(update_request)
|
|
return operations_util.WaitForOperation(api_client.client.apps_operations,
|
|
operation)
|
|
|
|
def Enable(self, oauth2_client_id, oauth2_client_secret):
|
|
"""Enable IAP on an App Engine Application."""
|
|
return self._SetAppEngineApplicationIap(True,
|
|
oauth2_client_id,
|
|
oauth2_client_secret)
|
|
|
|
def Disable(self):
|
|
"""Disable IAP on an App Engine Application."""
|
|
return self._SetAppEngineApplicationIap(False)
|
|
|
|
|
|
class AppEngineService(IapIamResource):
|
|
"""IAP IAM App Engine service resource.
|
|
"""
|
|
|
|
def __init__(self, release_track, project, service_id):
|
|
super(AppEngineService, self).__init__(release_track, project)
|
|
self.service_id = service_id
|
|
|
|
def _Name(self):
|
|
return 'App Engine application service'
|
|
|
|
def _Parse(self):
|
|
project = _GetProject(self.project)
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'project': project.projectNumber,
|
|
'iapWebId': _AppEngineAppId(project.projectId),
|
|
'serviceId': self.service_id,
|
|
},
|
|
collection=IAP_WEB_SERVICES_COLLECTION)
|
|
|
|
|
|
class AppEngineServiceVersion(IapIamResource):
|
|
"""IAP IAM App Engine service version resource.
|
|
"""
|
|
|
|
def __init__(self, release_track, project, service_id, version_id):
|
|
super(AppEngineServiceVersion, self).__init__(release_track, project)
|
|
self.service_id = service_id
|
|
self.version_id = version_id
|
|
|
|
def _Name(self):
|
|
return 'App Engine application service version'
|
|
|
|
def _Parse(self):
|
|
project = _GetProject(self.project)
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'project': project.projectNumber,
|
|
'iapWebId': _AppEngineAppId(project.projectId),
|
|
'serviceId': self.service_id,
|
|
'versionId': self.version_id,
|
|
},
|
|
collection=IAP_WEB_SERVICES_VERSIONS_COLLECTION)
|
|
|
|
|
|
BACKEND_SERVICES = 'compute'
|
|
|
|
|
|
class BackendServices(IapIamResource):
|
|
"""IAP IAM backend services resource.
|
|
"""
|
|
|
|
def __init__(self, release_track, project, region_id):
|
|
super(BackendServices, self).__init__(release_track, project)
|
|
self.region_id = region_id
|
|
|
|
def _Name(self):
|
|
return 'backend services'
|
|
|
|
def _IapWebId(self):
|
|
if self.region_id:
|
|
return '%s-%s' % (BACKEND_SERVICES, self.region_id)
|
|
else:
|
|
return BACKEND_SERVICES
|
|
|
|
def _Parse(self):
|
|
project = _GetProject(self.project)
|
|
iap_web_id = self._IapWebId()
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'project': project.projectNumber,
|
|
'iapWebId': iap_web_id,
|
|
},
|
|
collection=IAP_WEB_COLLECTION)
|
|
|
|
|
|
class BackendService(IapIamResource):
|
|
"""IAP IAM backend service resource.
|
|
"""
|
|
|
|
def __init__(self, release_track, project, region_id, service_id):
|
|
super(BackendService, self).__init__(release_track, project)
|
|
self.region_id = region_id
|
|
self.service_id = service_id
|
|
|
|
def _Name(self):
|
|
return 'backend service'
|
|
|
|
def _IapWebId(self):
|
|
if self.region_id:
|
|
return '%s-%s' % (BACKEND_SERVICES, self.region_id)
|
|
else:
|
|
return BACKEND_SERVICES
|
|
|
|
def _Parse(self):
|
|
project = _GetProject(self.project)
|
|
iap_web_id = self._IapWebId()
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'project': project.projectNumber,
|
|
'iapWebId': iap_web_id,
|
|
'serviceId': self.service_id,
|
|
},
|
|
collection=IAP_WEB_SERVICES_COLLECTION)
|
|
|
|
def _SetBackendServiceIap(self, enabled, oauth2_client_id=None,
|
|
oauth2_client_secret=None):
|
|
holder = base_classes.ComputeApiHolder(base.ReleaseTrack.GA)
|
|
client = holder.client
|
|
def MakeRequest(method, request):
|
|
if self.region_id:
|
|
return (
|
|
holder.client.apitools_client.regionBackendServices,
|
|
method,
|
|
request,
|
|
)
|
|
else:
|
|
return holder.client.apitools_client.backendServices, method, request
|
|
|
|
if self.region_id:
|
|
backend_service = holder.resources.Parse(
|
|
self.service_id,
|
|
params={
|
|
'project': self.project,
|
|
'region': self.region_id,
|
|
},
|
|
collection=COMPUTE_REGION_BACKEND_SERVICES_COLLECTION,
|
|
)
|
|
get_request = client.messages.ComputeRegionBackendServicesGetRequest(
|
|
project=backend_service.project,
|
|
region=backend_service.region,
|
|
backendService=backend_service.Name(),
|
|
)
|
|
else:
|
|
backend_service = holder.resources.Parse(
|
|
self.service_id,
|
|
params={
|
|
'project': self.project,
|
|
},
|
|
collection=COMPUTE_BACKEND_SERVICES_COLLECTION,
|
|
)
|
|
get_request = client.messages.ComputeBackendServicesGetRequest(
|
|
project=backend_service.project, backendService=backend_service.Name()
|
|
)
|
|
|
|
objects = client.MakeRequests([MakeRequest('Get', get_request)])
|
|
if (enabled and objects[0].protocol is
|
|
not client.messages.BackendService.ProtocolValueValuesEnum.HTTPS):
|
|
log.warning('IAP has been enabled for a backend service that does not '
|
|
'use HTTPS. Data sent from the Load Balancer to your VM will '
|
|
'not be encrypted.')
|
|
iap_kwargs = _MakeIAPKwargs(True, objects[0].iap, enabled,
|
|
oauth2_client_id, oauth2_client_secret)
|
|
replacement = encoding.CopyProtoMessage(objects[0])
|
|
replacement.iap = client.messages.BackendServiceIAP(**iap_kwargs)
|
|
|
|
if self.region_id:
|
|
update_request = client.messages.ComputeRegionBackendServicesPatchRequest(
|
|
project=backend_service.project,
|
|
region=backend_service.region,
|
|
backendService=backend_service.Name(),
|
|
backendServiceResource=replacement,
|
|
)
|
|
else:
|
|
update_request = client.messages.ComputeBackendServicesPatchRequest(
|
|
project=backend_service.project,
|
|
backendService=backend_service.Name(),
|
|
backendServiceResource=replacement)
|
|
|
|
return client.MakeRequests([MakeRequest('Patch', update_request)])
|
|
|
|
def Enable(self, oauth2_client_id, oauth2_client_secret):
|
|
"""Enable IAP on a backend service."""
|
|
return self._SetBackendServiceIap(True,
|
|
oauth2_client_id,
|
|
oauth2_client_secret)
|
|
|
|
def Disable(self):
|
|
"""Disable IAP on a backend service."""
|
|
return self._SetBackendServiceIap(False)
|
|
|
|
|
|
FORWARDING_RULE = 'forwarding_rule'
|
|
|
|
|
|
class ForwardingRules(IapIamResource):
|
|
"""IAP IAM forwarding rules resource.
|
|
"""
|
|
|
|
def __init__(self, release_track, project, region_id):
|
|
super(ForwardingRules, self).__init__(release_track, project)
|
|
self.region_id = region_id
|
|
|
|
def _Name(self):
|
|
return 'forwarding rules'
|
|
|
|
def _IapWebId(self):
|
|
if self.region_id:
|
|
return '%s-%s' % (FORWARDING_RULE, self.region_id)
|
|
else:
|
|
return FORWARDING_RULE
|
|
|
|
def _Parse(self):
|
|
project = _GetProject(self.project)
|
|
iap_web_id = self._IapWebId()
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'project': project.projectNumber,
|
|
'iapWebId': iap_web_id,
|
|
},
|
|
collection=IAP_WEB_COLLECTION)
|
|
|
|
|
|
class ForwardingRule(IapIamResource):
|
|
"""IAP IAM forwarding rule resource.
|
|
"""
|
|
|
|
def __init__(self, release_track, project, region_id, service_id):
|
|
super(ForwardingRule, self).__init__(release_track, project)
|
|
self.region_id = region_id
|
|
self.service_id = service_id
|
|
|
|
def _Name(self):
|
|
return 'forwarding rule'
|
|
|
|
def _IapWebId(self):
|
|
if self.region_id:
|
|
return '%s-%s' % (FORWARDING_RULE, self.region_id)
|
|
else:
|
|
return FORWARDING_RULE
|
|
|
|
def _Parse(self):
|
|
project = _GetProject(self.project)
|
|
iap_web_id = self._IapWebId()
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'project': project.projectNumber,
|
|
'iapWebId': iap_web_id,
|
|
'serviceId': self.service_id,
|
|
},
|
|
collection=IAP_WEB_SERVICES_COLLECTION)
|
|
|
|
|
|
CLOUD_RUN = 'cloud_run'
|
|
|
|
|
|
class CloudRuns(IapIamResource):
|
|
"""IAP IAM cloud runs resource.
|
|
"""
|
|
|
|
def __init__(self, release_track, project, region_id):
|
|
super(CloudRuns, self).__init__(release_track, project)
|
|
self.region_id = region_id
|
|
|
|
def _Name(self):
|
|
return 'cloud runs'
|
|
|
|
def _IapWebId(self):
|
|
return '%s-%s' % (CLOUD_RUN, self.region_id)
|
|
|
|
def _Parse(self):
|
|
project = _GetProject(self.project)
|
|
iap_web_id = self._IapWebId()
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'project': project.projectNumber,
|
|
'iapWebId': iap_web_id,
|
|
},
|
|
collection=IAP_WEB_COLLECTION)
|
|
|
|
|
|
class CloudRun(IapIamResource):
|
|
"""IAP IAM cloud run resource.
|
|
"""
|
|
|
|
def __init__(self, release_track, project, region_id, service_id):
|
|
super(CloudRun, self).__init__(release_track, project)
|
|
self.region_id = region_id
|
|
self.service_id = service_id
|
|
|
|
def _Name(self):
|
|
return 'cloud run'
|
|
|
|
def _IapWebId(self):
|
|
return '%s-%s' % (CLOUD_RUN, self.region_id)
|
|
|
|
def _Parse(self):
|
|
project = _GetProject(self.project)
|
|
iap_web_id = self._IapWebId()
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'project': project.projectNumber,
|
|
'iapWebId': iap_web_id,
|
|
'serviceId': self.service_id,
|
|
},
|
|
collection=IAP_WEB_SERVICES_COLLECTION)
|
|
|
|
|
|
def _MakeIAPKwargs(is_backend_service, existing_iap_settings, enabled,
|
|
oauth2_client_id, oauth2_client_secret):
|
|
"""Make IAP kwargs for IAP settings.
|
|
|
|
Args:
|
|
is_backend_service: boolean, True if we are applying IAP to a backend
|
|
service.
|
|
existing_iap_settings: appengine IdentityAwareProxy or compute
|
|
BackendServiceIAP, IAP settings.
|
|
enabled: boolean, True if IAP is enabled.
|
|
oauth2_client_id: OAuth2 client ID to use.
|
|
oauth2_client_secret: OAuth2 client secret to use.
|
|
|
|
Returns:
|
|
IAP kwargs for appengine IdentityAwareProxy or compute BackendServiceIAP
|
|
"""
|
|
|
|
if (is_backend_service and enabled and
|
|
not (existing_iap_settings and existing_iap_settings.enabled)):
|
|
log.warning('IAP only protects requests that go through the Cloud Load '
|
|
'Balancer. See the IAP documentation for important security '
|
|
'best practices: https://cloud.google.com/iap/.')
|
|
kwargs = {
|
|
'enabled': enabled,
|
|
}
|
|
if oauth2_client_id:
|
|
kwargs['oauth2ClientId'] = oauth2_client_id
|
|
if oauth2_client_secret:
|
|
kwargs['oauth2ClientSecret'] = oauth2_client_secret
|
|
return kwargs
|
|
|
|
|
|
class IapSettingsResource(object):
|
|
"""Class for IAP settings resources."""
|
|
|
|
def __init__(self, release_track, resource_name):
|
|
"""Constructor for IAP setting resource.
|
|
|
|
Args:
|
|
release_track: base.ReleaseTrack, release track of command.
|
|
resource_name: resource name for the iap settings.
|
|
"""
|
|
self.release_track = release_track
|
|
self.resource_name = resource_name
|
|
self.api_version = _ApiVersion(release_track)
|
|
self.client = apis.GetClientInstance(IAP_API, self.api_version)
|
|
self.registry = _GetRegistry(self.api_version)
|
|
|
|
@property
|
|
def messages(self):
|
|
return self.client.MESSAGES_MODULE
|
|
|
|
@property
|
|
def service(self):
|
|
return getattr(self.client, self.api_version)
|
|
|
|
def _ParseIapSettingsFile(self, iap_settings_file_path,
|
|
iap_settings_message_type):
|
|
"""Create an iap settings message from a JSON formatted file.
|
|
|
|
Args:
|
|
iap_settings_file_path: Path to iap_setttings JSON file
|
|
iap_settings_message_type: iap settings message type to convert JSON to
|
|
|
|
Returns:
|
|
the iap_settings message filled from JSON file
|
|
Raises:
|
|
BadFileException if JSON file is malformed.
|
|
"""
|
|
iap_settings_to_parse = yaml.load_path(iap_settings_file_path)
|
|
if (
|
|
'access_settings' in iap_settings_to_parse
|
|
and 'oauth_settings' in iap_settings_to_parse['access_settings']
|
|
and 'login_hint'
|
|
in iap_settings_to_parse['access_settings']['oauth_settings']
|
|
):
|
|
log.warning(
|
|
'login_hint setting is not a replacement for access control. Always'
|
|
' enforce an appropriate access policy if you want to restrict'
|
|
' access to users outside your domain.'
|
|
)
|
|
|
|
if (
|
|
'access_settings' in iap_settings_to_parse
|
|
and 'gcip_settings' in iap_settings_to_parse['access_settings']
|
|
):
|
|
log.warning(
|
|
'Enabling gcip_settings significantly changes the way IAP'
|
|
' authenticates users. Identity Platform does not support IAM, so'
|
|
' IAP will not enforce any IAM policies for requests to your'
|
|
' application.'
|
|
)
|
|
try:
|
|
iap_settings_message = encoding.PyValueToMessage(
|
|
iap_settings_message_type, iap_settings_to_parse
|
|
)
|
|
except AttributeError as e:
|
|
raise calliope_exceptions.BadFileException(
|
|
'Iap settings file {0} does not contain properly formatted JSON {1}'
|
|
.format(iap_settings_file_path, six.text_type(e))
|
|
)
|
|
return iap_settings_message
|
|
|
|
def GetIapSetting(self):
|
|
"""Get the setting for an IAP resource."""
|
|
request = self.messages.IapGetIapSettingsRequest(name=self.resource_name)
|
|
return self.service.GetIapSettings(request)
|
|
|
|
def SetIapSetting(self, setting_file):
|
|
"""Set the setting for an IAP resource."""
|
|
iap_settings = self._ParseIapSettingsFile(
|
|
setting_file, self.messages.IapSettings
|
|
)
|
|
iap_settings.name = self.resource_name
|
|
request = self.messages.IapUpdateIapSettingsRequest(
|
|
iapSettings=iap_settings, name=self.resource_name
|
|
)
|
|
return self.service.UpdateIapSettings(request)
|
|
|
|
|
|
class IapTunnelDestGroupResource(IapIamResource):
|
|
"""IAP TCP tunnelDestGroup IAM resource."""
|
|
|
|
def __init__(self, release_track, project, region='-', group_name=None):
|
|
super(IapTunnelDestGroupResource, self).__init__(release_track, project)
|
|
self.region = region
|
|
self.group_name = group_name
|
|
|
|
def ResourceService(self):
|
|
return getattr(self.client, 'projects_iap_tunnel_locations_destGroups')
|
|
|
|
def _Name(self):
|
|
return 'iap_tunneldestgroups'
|
|
|
|
def _Parse(self):
|
|
if self.group_name is None:
|
|
return self._ParseWithoutGroupId()
|
|
return self._ParseWithGroupId()
|
|
|
|
def _ParseWithGroupId(self):
|
|
project_number = _GetProject(self.project).projectNumber
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'projectsId': project_number,
|
|
'locationsId': self.region,
|
|
'destGroupsId': self.group_name,
|
|
},
|
|
collection=IAP_TCP_DESTGROUP_COLLECTION)
|
|
|
|
def _ParseWithoutGroupId(self):
|
|
self.project_number = _GetProject(self.project).projectNumber
|
|
return self.registry.Parse(
|
|
None,
|
|
params={
|
|
'projectsId': self.project_number,
|
|
'locationsId': self.region,
|
|
},
|
|
collection=IAP_TCP_LOCATIONS_COLLECTION)
|
|
|
|
def _CreateTunnelDestGroupObject(self, cidr_list, fqdn_list):
|
|
return {
|
|
'name': self.group_name,
|
|
'cidrs': cidr_list.split(',') if cidr_list else [],
|
|
'fqdns': fqdn_list.split(',') if fqdn_list else [],
|
|
}
|
|
|
|
def Create(self, cidr_list, fqdn_list):
|
|
"""Creates a TunnelDestGroup."""
|
|
|
|
tunnel_dest_group = self._CreateTunnelDestGroupObject(cidr_list, fqdn_list)
|
|
request = (
|
|
self.messages.IapProjectsIapTunnelLocationsDestGroupsCreateRequest(
|
|
parent=self._ParseWithoutGroupId().RelativeName(),
|
|
tunnelDestGroup=tunnel_dest_group,
|
|
tunnelDestGroupId=self.group_name,
|
|
)
|
|
)
|
|
return self.ResourceService().Create(request)
|
|
|
|
def Delete(self):
|
|
"""Deletes the TunnelDestGroup."""
|
|
request = (
|
|
self.messages.IapProjectsIapTunnelLocationsDestGroupsDeleteRequest(
|
|
name=self._Parse().RelativeName()
|
|
)
|
|
)
|
|
return self.ResourceService().Delete(request)
|
|
|
|
def List(self, page_size=None, limit=None, list_filter=None):
|
|
"""Yields TunnelDestGroups."""
|
|
list_req = self.messages.IapProjectsIapTunnelLocationsDestGroupsListRequest(
|
|
parent=self._ParseWithoutGroupId().RelativeName()
|
|
)
|
|
return list_pager.YieldFromList(
|
|
self.ResourceService(),
|
|
list_req,
|
|
batch_size=page_size,
|
|
limit=limit,
|
|
field='tunnelDestGroups',
|
|
batch_size_attribute='pageSize',
|
|
)
|
|
|
|
def Get(self):
|
|
"""Get TunnelDestGroup."""
|
|
request = self.messages.IapProjectsIapTunnelLocationsDestGroupsGetRequest(
|
|
name=self._Parse().RelativeName()
|
|
)
|
|
return self.ResourceService().Get(request)
|
|
|
|
def Update(self, cidr_list, fqdn_list, update_mask):
|
|
"""Update TunnelDestGroup."""
|
|
|
|
tunnel_dest_group = self._CreateTunnelDestGroupObject(cidr_list, fqdn_list)
|
|
|
|
request = self.messages.IapProjectsIapTunnelLocationsDestGroupsPatchRequest(
|
|
name=self._Parse().RelativeName(),
|
|
tunnelDestGroup=tunnel_dest_group,
|
|
updateMask=update_mask)
|
|
return self.ResourceService().Patch(request)
|