356 lines
12 KiB
Python
356 lines
12 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2018 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.
|
|
"""Bigtable app-profiles API helper."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
from apitools.base.py import list_pager
|
|
from googlecloudsdk.api_lib.bigtable import util
|
|
from googlecloudsdk.calliope import exceptions
|
|
|
|
|
|
def Describe(app_profile_ref):
|
|
"""Describe an app profile.
|
|
|
|
Args:
|
|
app_profile_ref: A resource reference to the app profile to describe.
|
|
|
|
Returns:
|
|
App profile resource object.
|
|
"""
|
|
client = util.GetAdminClient()
|
|
msg = util.GetAdminMessages().BigtableadminProjectsInstancesAppProfilesGetRequest(
|
|
name=app_profile_ref.RelativeName()
|
|
)
|
|
return client.projects_instances_appProfiles.Get(msg)
|
|
|
|
|
|
def List(instance_ref):
|
|
"""List app profiles.
|
|
|
|
Args:
|
|
instance_ref: A resource reference of the instance to list app profiles for.
|
|
|
|
Returns:
|
|
Generator of app profile resource objects.
|
|
"""
|
|
client = util.GetAdminClient()
|
|
msg = util.GetAdminMessages().BigtableadminProjectsInstancesAppProfilesListRequest(
|
|
parent=instance_ref.RelativeName()
|
|
)
|
|
return list_pager.YieldFromList(
|
|
client.projects_instances_appProfiles,
|
|
msg,
|
|
field='appProfiles',
|
|
batch_size_attribute=None,
|
|
)
|
|
|
|
|
|
def Delete(app_profile_ref, force=False):
|
|
"""Delete an app profile.
|
|
|
|
Args:
|
|
app_profile_ref: A resource reference to the app profile to delete.
|
|
force: bool, Whether to ignore API warnings and delete forcibly.
|
|
|
|
Returns:
|
|
Empty response.
|
|
"""
|
|
client = util.GetAdminClient()
|
|
msg = util.GetAdminMessages().BigtableadminProjectsInstancesAppProfilesDeleteRequest(
|
|
name=app_profile_ref.RelativeName(), ignoreWarnings=force
|
|
)
|
|
return client.projects_instances_appProfiles.Delete(msg)
|
|
|
|
|
|
def _AppProfileChecks(
|
|
cluster=None,
|
|
multi_cluster=False,
|
|
restrict_to=None,
|
|
transactional_writes=None,
|
|
row_affinity=False,
|
|
data_boost=False,
|
|
):
|
|
"""Create an app profile.
|
|
|
|
Args:
|
|
cluster: string, The cluster id for the new app profile to route to using
|
|
single cluster routing.
|
|
multi_cluster: bool, Whether this app profile should route to multiple
|
|
clusters, instead of single cluster.
|
|
restrict_to: list[string] The list of cluster ids for the new app profile to
|
|
route to using multi cluster routing.
|
|
transactional_writes: bool, Whether this app profile has transactional
|
|
writes enabled. This is only possible when using single cluster routing.
|
|
row_affinity: bool, Whether to use row affinity sticky routing.
|
|
data_boost: bool, If the app profile should use Data Boost Read-only
|
|
Isolation.
|
|
|
|
Raises:
|
|
ConflictingArgumentsException:
|
|
If both cluster and multi_cluster are present.
|
|
If both multi_cluster and transactional_writes are present.
|
|
If both cluster and row_affinity are present.
|
|
If both cluster and restrict_to are present.
|
|
If both multi_cluster and data_boost are present.
|
|
If both transactional_writes and data_boost are present.
|
|
|
|
OneOfArgumentsRequiredException: If neither cluster or multi_cluster are
|
|
present.
|
|
"""
|
|
if multi_cluster and cluster:
|
|
raise exceptions.ConflictingArgumentsException('--route-to', '--route-any')
|
|
if not multi_cluster and not cluster:
|
|
raise exceptions.OneOfArgumentsRequiredException(
|
|
['--route-to', '--route-any'],
|
|
'Either --route-to or --route-any must be specified.',
|
|
)
|
|
|
|
if multi_cluster and transactional_writes:
|
|
raise exceptions.ConflictingArgumentsException(
|
|
'--route-any', '--transactional-writes'
|
|
)
|
|
if cluster and row_affinity:
|
|
raise exceptions.ConflictingArgumentsException(
|
|
'--route-to', '--row-affinity'
|
|
)
|
|
if cluster and restrict_to:
|
|
raise exceptions.ConflictingArgumentsException(
|
|
'--route-to', '--restrict-to'
|
|
)
|
|
|
|
# Data Boost.
|
|
if multi_cluster and data_boost:
|
|
raise exceptions.ConflictingArgumentsException(
|
|
'--route-any', '--data-boost'
|
|
)
|
|
if transactional_writes and data_boost:
|
|
raise exceptions.ConflictingArgumentsException(
|
|
'--transactional-writes', '--data-boost'
|
|
)
|
|
|
|
|
|
def Create(
|
|
app_profile_ref,
|
|
cluster=None,
|
|
description='',
|
|
multi_cluster=False,
|
|
restrict_to=None,
|
|
transactional_writes=None,
|
|
row_affinity=False,
|
|
priority=None,
|
|
data_boost=False,
|
|
data_boost_compute_billing_owner=None,
|
|
force=False,
|
|
):
|
|
"""Create an app profile.
|
|
|
|
Args:
|
|
app_profile_ref: A resource reference of the new app profile.
|
|
cluster: string, The cluster id for the new app profile to route to using
|
|
single cluster routing.
|
|
description: string, A description of the new app profile.
|
|
multi_cluster: bool, Whether this app profile should route to multiple
|
|
clusters, instead of single cluster.
|
|
restrict_to: list[string] The list of cluster ids for the new app profile to
|
|
route to using multi cluster routing.
|
|
transactional_writes: bool, Whether this app profile has transactional
|
|
writes enabled. This is only possible when using single cluster routing.
|
|
row_affinity: bool, Whether to use row affinity sticky routing.
|
|
priority: string, The request priority of the new app profile.
|
|
data_boost: bool, If the app profile should use Standard Isolation.
|
|
data_boost_compute_billing_owner: string, The compute billing owner for Data
|
|
Boost.
|
|
force: bool, Whether to ignore API warnings and create forcibly.
|
|
|
|
Raises:
|
|
ConflictingArgumentsException,
|
|
OneOfArgumentsRequiredException:
|
|
See _AppProfileChecks(...)
|
|
|
|
Returns:
|
|
Created app profile resource object.
|
|
"""
|
|
_AppProfileChecks(
|
|
cluster=cluster,
|
|
multi_cluster=multi_cluster,
|
|
restrict_to=restrict_to,
|
|
transactional_writes=transactional_writes,
|
|
row_affinity=row_affinity,
|
|
data_boost=data_boost,
|
|
)
|
|
|
|
client = util.GetAdminClient()
|
|
msgs = util.GetAdminMessages()
|
|
|
|
instance_ref = app_profile_ref.Parent()
|
|
|
|
multi_cluster_routing = None
|
|
single_cluster_routing = None
|
|
if multi_cluster:
|
|
multi_cluster_routing = msgs.MultiClusterRoutingUseAny(
|
|
clusterIds=restrict_to or [],
|
|
rowAffinity=msgs.RowAffinity() if row_affinity else None,
|
|
)
|
|
elif cluster:
|
|
single_cluster_routing = msgs.SingleClusterRouting(
|
|
clusterId=cluster,
|
|
allowTransactionalWrites=transactional_writes,
|
|
)
|
|
|
|
standard_isolation = None
|
|
data_boost_isolation = None
|
|
if priority:
|
|
priority_enum = msgs.StandardIsolation.PriorityValueValuesEnum(priority)
|
|
standard_isolation = msgs.StandardIsolation(priority=priority_enum)
|
|
elif data_boost:
|
|
data_boost_enum = (
|
|
msgs.DataBoostIsolationReadOnly.ComputeBillingOwnerValueValuesEnum(
|
|
data_boost_compute_billing_owner
|
|
)
|
|
)
|
|
data_boost_isolation = msgs.DataBoostIsolationReadOnly(
|
|
computeBillingOwner=data_boost_enum
|
|
)
|
|
|
|
msg = msgs.BigtableadminProjectsInstancesAppProfilesCreateRequest(
|
|
appProfile=msgs.AppProfile(
|
|
description=description,
|
|
multiClusterRoutingUseAny=multi_cluster_routing,
|
|
singleClusterRouting=single_cluster_routing,
|
|
standardIsolation=standard_isolation,
|
|
dataBoostIsolationReadOnly=data_boost_isolation,
|
|
),
|
|
appProfileId=app_profile_ref.Name(),
|
|
parent=instance_ref.RelativeName(),
|
|
ignoreWarnings=force,
|
|
)
|
|
return client.projects_instances_appProfiles.Create(msg)
|
|
|
|
|
|
def Update(
|
|
app_profile_ref,
|
|
cluster=None,
|
|
description='',
|
|
multi_cluster=False,
|
|
restrict_to=None,
|
|
transactional_writes=None,
|
|
row_affinity=None,
|
|
priority=None,
|
|
data_boost=False,
|
|
data_boost_compute_billing_owner=None,
|
|
force=False,
|
|
):
|
|
"""Update an app profile.
|
|
|
|
Args:
|
|
app_profile_ref: A resource reference of the app profile to update.
|
|
cluster: string, The cluster id for the app profile to route to using single
|
|
cluster routing.
|
|
description: string, A description of the app profile.
|
|
multi_cluster: bool, Whether this app profile should route to multiple
|
|
clusters, instead of single cluster.
|
|
restrict_to: list[string] The list of cluster IDs for the app profile to
|
|
route to using multi cluster routing.
|
|
transactional_writes: bool, Whether this app profile has transactional
|
|
writes enabled. This is only possible when using single cluster routing.
|
|
row_affinity: bool, Whether to use row affinity sticky routing. If None,
|
|
then no change should be made.
|
|
priority: string, The request priority of the new app profile.
|
|
data_boost: bool, If the app profile should use Standard Isolation.
|
|
data_boost_compute_billing_owner: string, The compute billing owner for Data
|
|
Boost.
|
|
force: bool, Whether to ignore API warnings and create forcibly.
|
|
|
|
Raises:
|
|
ConflictingArgumentsException,
|
|
OneOfArgumentsRequiredException:
|
|
See _AppProfileChecks(...)
|
|
|
|
Returns:
|
|
Long running operation.
|
|
"""
|
|
_AppProfileChecks(
|
|
cluster=cluster,
|
|
multi_cluster=multi_cluster,
|
|
restrict_to=restrict_to,
|
|
transactional_writes=transactional_writes,
|
|
row_affinity=row_affinity,
|
|
data_boost=data_boost,
|
|
)
|
|
|
|
client = util.GetAdminClient()
|
|
msgs = util.GetAdminMessages()
|
|
|
|
changed_fields = []
|
|
app_profile = msgs.AppProfile()
|
|
|
|
if cluster:
|
|
changed_fields.append('singleClusterRouting.clusterId')
|
|
if transactional_writes is not None:
|
|
changed_fields.append('singleClusterRouting.allowTransactionalWrites')
|
|
app_profile.singleClusterRouting = msgs.SingleClusterRouting(
|
|
clusterId=cluster,
|
|
allowTransactionalWrites=transactional_writes,
|
|
)
|
|
elif multi_cluster:
|
|
if restrict_to:
|
|
changed_fields.append('multiClusterRoutingUseAny.clusterIds')
|
|
if row_affinity is not None:
|
|
changed_fields.append('multiClusterRoutingUseAny.rowAffinity')
|
|
app_profile.multiClusterRoutingUseAny = msgs.MultiClusterRoutingUseAny(
|
|
clusterIds=restrict_to or [],
|
|
rowAffinity=msgs.RowAffinity() if row_affinity else None,
|
|
)
|
|
# If the only update is from single cluster to default multi cluster config,
|
|
# then set the field mask to be the entire proto message.
|
|
if (
|
|
app_profile.multiClusterRoutingUseAny
|
|
== msgs.MultiClusterRoutingUseAny()
|
|
):
|
|
changed_fields.append('multiClusterRoutingUseAny')
|
|
|
|
if description:
|
|
changed_fields.append('description')
|
|
app_profile.description = description
|
|
|
|
if priority:
|
|
priority_enum = msgs.StandardIsolation.PriorityValueValuesEnum(priority)
|
|
changed_fields.append('standardIsolation.priority')
|
|
app_profile.standardIsolation = msgs.StandardIsolation(
|
|
priority=priority_enum
|
|
)
|
|
|
|
elif data_boost:
|
|
data_boost_enum = (
|
|
msgs.DataBoostIsolationReadOnly.ComputeBillingOwnerValueValuesEnum(
|
|
data_boost_compute_billing_owner
|
|
)
|
|
)
|
|
changed_fields.append('dataBoostIsolationReadOnly')
|
|
app_profile.dataBoostIsolationReadOnly = msgs.DataBoostIsolationReadOnly(
|
|
computeBillingOwner=data_boost_enum
|
|
)
|
|
|
|
msg = msgs.BigtableadminProjectsInstancesAppProfilesPatchRequest(
|
|
appProfile=app_profile,
|
|
name=app_profile_ref.RelativeName(),
|
|
updateMask=','.join(changed_fields),
|
|
ignoreWarnings=force,
|
|
)
|
|
return client.projects_instances_appProfiles.Patch(msg)
|