File: //snap/google-cloud-cli/394/lib/googlecloudsdk/api_lib/bigtable/app_profiles.py
# -*- 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)