1586 lines
61 KiB
Python
1586 lines
61 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2021 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.
|
|
"""Helper functions for constructing and validating AlloyDB instance requests."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
from googlecloudsdk.api_lib.alloydb import api_util
|
|
from googlecloudsdk.calliope import base
|
|
from googlecloudsdk.calliope.parser_errors import DetailedArgumentError
|
|
from googlecloudsdk.command_lib.util.args import labels_util
|
|
from googlecloudsdk.core import properties
|
|
|
|
|
|
def ConstructCreateRequestFromArgsGA(
|
|
client, alloydb_messages, project_ref, args
|
|
):
|
|
"""Validates command line input arguments and passes parent's resources for GA track.
|
|
|
|
Args:
|
|
client: Client for api_utils.py class.
|
|
alloydb_messages: Messages module for the API client.
|
|
project_ref: parent resource path of the resource being created
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
Fully-constructed request to create an AlloyDB instance.
|
|
"""
|
|
instance_resource = _ConstructInstanceFromArgs(client, alloydb_messages, args)
|
|
|
|
return (
|
|
alloydb_messages.AlloydbProjectsLocationsClustersInstancesCreateRequest(
|
|
instance=instance_resource,
|
|
instanceId=args.instance,
|
|
parent=project_ref.RelativeName(),
|
|
)
|
|
)
|
|
|
|
|
|
def ConstructCreateRequestFromArgsBeta(
|
|
client, alloydb_messages, project_ref, args
|
|
):
|
|
"""Validates command line input arguments and passes parent's resources for beta tracks.
|
|
|
|
Args:
|
|
client: Client for api_utils.py class.
|
|
alloydb_messages: Messages module for the API client.
|
|
project_ref: Parent resource path of the resource being created
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
Fully-constructed request to create an AlloyDB instance.
|
|
"""
|
|
instance_resource = _ConstructInstanceFromArgsBeta(
|
|
client, alloydb_messages, args
|
|
)
|
|
|
|
return (
|
|
alloydb_messages.AlloydbProjectsLocationsClustersInstancesCreateRequest(
|
|
instance=instance_resource,
|
|
instanceId=args.instance,
|
|
parent=project_ref.RelativeName(),
|
|
)
|
|
)
|
|
|
|
|
|
def ConstructCreateRequestFromArgsAlpha(
|
|
client, alloydb_messages, project_ref, args
|
|
):
|
|
"""Validates command line input arguments and passes parent's resources for alpha track.
|
|
|
|
Args:
|
|
client: Client for api_utils.py class.
|
|
alloydb_messages: Messages module for the API client.
|
|
project_ref: Parent resource path of the resource being created
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
Fully-constructed request to create an AlloyDB instance.
|
|
"""
|
|
instance_resource = _ConstructInstanceFromArgsAlpha(
|
|
client, alloydb_messages, args
|
|
)
|
|
|
|
return (
|
|
alloydb_messages.AlloydbProjectsLocationsClustersInstancesCreateRequest(
|
|
instance=instance_resource,
|
|
instanceId=args.instance,
|
|
parent=project_ref.RelativeName(),
|
|
)
|
|
)
|
|
|
|
|
|
def ConstructCreateMachineConfigFromArgs(alloydb_messages, args):
|
|
"""Validates command line input arguments and creates a MachineConfig object."""
|
|
if args.cpu_count or args.machine_type:
|
|
return alloydb_messages.MachineConfig(
|
|
cpuCount=args.cpu_count, machineType=args.machine_type
|
|
)
|
|
else:
|
|
raise DetailedArgumentError(
|
|
'Either --cpu-count or --machine-type must be specified.'
|
|
)
|
|
|
|
|
|
def _ConstructInstanceFromArgs(client, alloydb_messages, args):
|
|
"""Validates command line input arguments and passes parent's resources to create an AlloyDB instance.
|
|
|
|
Args:
|
|
client: Client for api_utils.py class.
|
|
alloydb_messages: Messages module for the API client.
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
An AlloyDB instance to create with the specified command line arguments.
|
|
"""
|
|
instance_resource = alloydb_messages.Instance()
|
|
|
|
# set availability-type if provided
|
|
instance_resource.availabilityType = ParseAvailabilityType(
|
|
alloydb_messages, args.availability_type
|
|
)
|
|
instance_resource.machineConfig = ConstructCreateMachineConfigFromArgs(
|
|
alloydb_messages, args
|
|
)
|
|
instance_ref = client.resource_parser.Create(
|
|
'alloydb.projects.locations.clusters.instances',
|
|
projectsId=properties.VALUES.core.project.GetOrFail,
|
|
locationsId=args.region,
|
|
clustersId=args.cluster,
|
|
instancesId=args.instance,
|
|
)
|
|
instance_resource.name = instance_ref.RelativeName()
|
|
|
|
instance_resource.databaseFlags = labels_util.ParseCreateArgs(
|
|
args,
|
|
alloydb_messages.Instance.DatabaseFlagsValue,
|
|
labels_dest='database_flags',
|
|
)
|
|
instance_resource.instanceType = _ParseInstanceType(
|
|
alloydb_messages, args.instance_type
|
|
)
|
|
|
|
if (
|
|
instance_resource.instanceType
|
|
== alloydb_messages.Instance.InstanceTypeValueValuesEnum.READ_POOL
|
|
):
|
|
instance_resource.readPoolConfig = alloydb_messages.ReadPoolConfig(
|
|
nodeCount=args.read_pool_node_count
|
|
)
|
|
|
|
instance_resource.queryInsightsConfig = _QueryInsightsConfig(
|
|
alloydb_messages,
|
|
insights_config_query_string_length=args.insights_config_query_string_length,
|
|
insights_config_query_plans_per_minute=args.insights_config_query_plans_per_minute,
|
|
insights_config_record_application_tags=args.insights_config_record_application_tags,
|
|
insights_config_record_client_address=args.insights_config_record_client_address,
|
|
)
|
|
|
|
instance_resource.clientConnectionConfig = ClientConnectionConfig(
|
|
alloydb_messages,
|
|
args.ssl_mode,
|
|
args.require_connectors,
|
|
)
|
|
|
|
instance_resource.networkConfig = NetworkConfig(
|
|
alloydb_messages=alloydb_messages,
|
|
assign_inbound_public_ip=args.assign_inbound_public_ip,
|
|
authorized_external_networks=args.authorized_external_networks,
|
|
outbound_public_ip=args.outbound_public_ip,
|
|
allocated_ip_range_override=args.allocated_ip_range_override,
|
|
)
|
|
|
|
if (
|
|
args.allowed_psc_projects
|
|
or args.psc_network_attachment_uri is not None
|
|
or args.psc_auto_connections is not None
|
|
):
|
|
instance_resource.pscInstanceConfig = PscInstanceConfig(
|
|
alloydb_messages=alloydb_messages,
|
|
allowed_psc_projects=args.allowed_psc_projects,
|
|
psc_network_attachment_uri=args.psc_network_attachment_uri,
|
|
psc_auto_connections=args.psc_auto_connections,
|
|
)
|
|
|
|
if args.enable_connection_pooling:
|
|
instance_resource.connectionPoolConfig = _ConnectionPoolConfig(
|
|
alloydb_messages=alloydb_messages,
|
|
enable_connection_pooling=args.enable_connection_pooling,
|
|
connection_pooling_pool_mode=args.connection_pooling_pool_mode,
|
|
connection_pooling_min_pool_size=args.connection_pooling_min_pool_size,
|
|
connection_pooling_max_pool_size=args.connection_pooling_max_pool_size,
|
|
connection_pooling_max_client_conn=args.connection_pooling_max_client_connections,
|
|
connection_pooling_server_idle_timeout=args.connection_pooling_server_idle_timeout,
|
|
connection_pooling_query_wait_timeout=args.connection_pooling_query_wait_timeout,
|
|
connection_pooling_stats_users=args.connection_pooling_stats_users,
|
|
connection_pooling_ignore_startup_parameters=args.connection_pooling_ignore_startup_parameters,
|
|
connection_pooling_server_lifetime=args.connection_pooling_server_lifetime,
|
|
connection_pooling_client_connection_idle_timeout=args.connection_pooling_client_connection_idle_timeout,
|
|
connection_pooling_max_prepared_statements=args.connection_pooling_max_prepared_statements,
|
|
args=args,
|
|
)
|
|
|
|
return instance_resource
|
|
|
|
|
|
def _ConstructInstanceFromArgsBeta(client, alloydb_messages, args):
|
|
"""Validates command line input arguments and passes parent's resources to create an AlloyDB instance for beta track.
|
|
|
|
Args:
|
|
client: Client for api_utils.py class.
|
|
alloydb_messages: Messages module for the API client.
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
An AlloyDB instance to create with the specified command line arguments.
|
|
"""
|
|
instance_resource = _ConstructInstanceFromArgs(client, alloydb_messages, args)
|
|
instance_resource.observabilityConfig = _ObservabilityConfig(
|
|
alloydb_messages,
|
|
observability_config_enabled=args.observability_config_enabled,
|
|
observability_config_preserve_comments=args.observability_config_preserve_comments,
|
|
observability_config_track_wait_events=args.observability_config_track_wait_events,
|
|
observability_config_max_query_string_length=args.observability_config_max_query_string_length,
|
|
observability_config_record_application_tags=args.observability_config_record_application_tags,
|
|
observability_config_query_plans_per_minute=args.observability_config_query_plans_per_minute,
|
|
observability_config_track_active_queries=args.observability_config_track_active_queries,
|
|
)
|
|
|
|
if (
|
|
args.autoscaler_max_node_count is not None
|
|
or args.autoscaler_cool_down_period_seconds is not None
|
|
or args.autoscaler_target_cpu_usage is not None
|
|
or args.enable_autoscaler is not None
|
|
or args.autoscaler_set_schedule is not None
|
|
or args.autoscaler_schedule_cron_exp is not None
|
|
or args.autoscaler_schedule_duration_seconds is not None
|
|
or args.autoscaler_schedule_min_node_count is not None
|
|
or args.autoscaler_schedule_time_zone is not None
|
|
or args.autoscaler_schedule_description is not None
|
|
):
|
|
auto_scaling_config = ParseAutoScalingConfig(
|
|
alloydb_messages, None, None, args
|
|
)
|
|
if not instance_resource.readPoolConfig:
|
|
instance_resource.readPoolConfig = alloydb_messages.ReadPoolConfig()
|
|
instance_resource.readPoolConfig.autoScalingConfig = auto_scaling_config
|
|
|
|
return instance_resource
|
|
|
|
|
|
def _ConstructInstanceFromArgsAlpha(client, alloydb_messages, args):
|
|
"""Validates command line input arguments and passes parent's resources to create an AlloyDB instance for alpha track.
|
|
|
|
Args:
|
|
client: Client for api_utils.py class.
|
|
alloydb_messages: Messages module for the API client.
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
An AlloyDB instance to create with the specified command line arguments.
|
|
"""
|
|
instance_resource = _ConstructInstanceFromArgsBeta(
|
|
client, alloydb_messages, args
|
|
)
|
|
|
|
return instance_resource
|
|
|
|
|
|
def _ConstructSecondaryInstanceFromArgs(client, alloydb_messages, args):
|
|
"""Validates command line input arguments and passes parent's resources to create an AlloyDB secondary instance."""
|
|
|
|
instance_resource = alloydb_messages.Instance()
|
|
instance_ref = client.resource_parser.Create(
|
|
'alloydb.projects.locations.clusters.instances',
|
|
projectsId=properties.VALUES.core.project.GetOrFail,
|
|
locationsId=args.region,
|
|
clustersId=args.cluster,
|
|
instancesId=args.instance,
|
|
)
|
|
instance_resource.name = instance_ref.RelativeName()
|
|
instance_resource.instanceType = (
|
|
alloydb_messages.Instance.InstanceTypeValueValuesEnum.SECONDARY
|
|
)
|
|
instance_resource.availabilityType = ParseAvailabilityType(
|
|
alloydb_messages, args.availability_type
|
|
)
|
|
instance_resource.clientConnectionConfig = ClientConnectionConfig(
|
|
alloydb_messages, args.ssl_mode, args.require_connectors
|
|
)
|
|
instance_resource.databaseFlags = labels_util.ParseCreateArgs(
|
|
args,
|
|
alloydb_messages.Instance.DatabaseFlagsValue,
|
|
labels_dest='database_flags',
|
|
)
|
|
instance_resource.networkConfig = NetworkConfig(
|
|
alloydb_messages=alloydb_messages,
|
|
assign_inbound_public_ip=args.assign_inbound_public_ip,
|
|
authorized_external_networks=args.authorized_external_networks,
|
|
outbound_public_ip=args.outbound_public_ip,
|
|
allocated_ip_range_override=args.allocated_ip_range_override,
|
|
)
|
|
if (
|
|
args.allowed_psc_projects
|
|
or args.psc_network_attachment_uri is not None
|
|
or args.psc_auto_connections is not None
|
|
):
|
|
instance_resource.pscInstanceConfig = PscInstanceConfig(
|
|
alloydb_messages=alloydb_messages,
|
|
allowed_psc_projects=args.allowed_psc_projects,
|
|
psc_network_attachment_uri=args.psc_network_attachment_uri,
|
|
psc_auto_connections=args.psc_auto_connections,
|
|
)
|
|
|
|
if args.enable_connection_pooling:
|
|
instance_resource.connectionPoolConfig = _ConnectionPoolConfig(
|
|
alloydb_messages=alloydb_messages,
|
|
enable_connection_pooling=args.enable_connection_pooling,
|
|
connection_pooling_pool_mode=args.connection_pooling_pool_mode,
|
|
connection_pooling_min_pool_size=args.connection_pooling_min_pool_size,
|
|
connection_pooling_max_pool_size=args.connection_pooling_max_pool_size,
|
|
connection_pooling_max_client_conn=args.connection_pooling_max_client_connections,
|
|
connection_pooling_server_idle_timeout=args.connection_pooling_server_idle_timeout,
|
|
connection_pooling_query_wait_timeout=args.connection_pooling_query_wait_timeout,
|
|
connection_pooling_stats_users=args.connection_pooling_stats_users,
|
|
connection_pooling_ignore_startup_parameters=args.connection_pooling_ignore_startup_parameters,
|
|
connection_pooling_server_lifetime=args.connection_pooling_server_lifetime,
|
|
connection_pooling_client_connection_idle_timeout=args.connection_pooling_client_connection_idle_timeout,
|
|
connection_pooling_max_prepared_statements=args.connection_pooling_max_prepared_statements,
|
|
args=args,
|
|
)
|
|
|
|
return instance_resource
|
|
|
|
|
|
def _ConstructSecondaryInstanceFromArgsBeta(client, alloydb_messages, args):
|
|
"""Validates command line input arguments and passes parent's resources to create an AlloyDB secondary instance for beta track.
|
|
|
|
Args:
|
|
client: Client for api_utils.py class.
|
|
alloydb_messages: Messages module for the API client.
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
An AlloyDB secondary instance to create with the specified command line
|
|
arguments.
|
|
"""
|
|
|
|
return _ConstructSecondaryInstanceFromArgs(
|
|
client, alloydb_messages, args
|
|
)
|
|
|
|
|
|
def _ConstructSecondaryInstanceFromArgsAlpha(client, alloydb_messages, args):
|
|
"""Validates command line input arguments and passes parent's resources to create an AlloyDB secondary instance for alpha track.
|
|
|
|
Args:
|
|
client: Client for api_utils.py class.
|
|
alloydb_messages: Messages module for the API client.
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
An AlloyDB secondary instance to create with the specified command line
|
|
arguments.
|
|
"""
|
|
|
|
instance_resource = _ConstructSecondaryInstanceFromArgsBeta(
|
|
client, alloydb_messages, args
|
|
)
|
|
|
|
return instance_resource
|
|
|
|
|
|
def ConstructSecondaryCreateRequestFromArgsGA(
|
|
client, alloydb_messages, cluster_ref, args
|
|
):
|
|
"""Validates command line input arguments and passes parent's resources for GA track."""
|
|
|
|
instance_resource = _ConstructSecondaryInstanceFromArgs(
|
|
client, alloydb_messages, args
|
|
)
|
|
|
|
return alloydb_messages.AlloydbProjectsLocationsClustersInstancesCreatesecondaryRequest(
|
|
instance=instance_resource,
|
|
instanceId=args.instance,
|
|
parent=cluster_ref.RelativeName(),
|
|
)
|
|
|
|
|
|
def ConstructSecondaryCreateRequestFromArgsBeta(
|
|
client, alloydb_messages, cluster_ref, args
|
|
):
|
|
"""Validates command line input arguments and passes parent's resources for beta track."""
|
|
instance_resource = _ConstructSecondaryInstanceFromArgsBeta(
|
|
client, alloydb_messages, args
|
|
)
|
|
return alloydb_messages.AlloydbProjectsLocationsClustersInstancesCreatesecondaryRequest(
|
|
instance=instance_resource,
|
|
instanceId=args.instance,
|
|
parent=cluster_ref.RelativeName(),
|
|
)
|
|
|
|
|
|
def ConstructSecondaryCreateRequestFromArgsAlpha(
|
|
client, alloydb_messages, cluster_ref, args
|
|
):
|
|
"""Validates command line input arguments and passes parent's resources for alpha track."""
|
|
instance_resource = _ConstructSecondaryInstanceFromArgsAlpha(
|
|
client, alloydb_messages, args
|
|
)
|
|
return alloydb_messages.AlloydbProjectsLocationsClustersInstancesCreatesecondaryRequest(
|
|
instance=instance_resource,
|
|
instanceId=args.instance,
|
|
parent=cluster_ref.RelativeName(),
|
|
)
|
|
|
|
|
|
def ConstructPatchRequestFromArgs(alloydb_messages, instance_ref, args):
|
|
"""Constructs the request to update an AlloyDB instance.
|
|
|
|
Args:
|
|
alloydb_messages: Messages module for the API client.
|
|
instance_ref: parent resource path of the resource being updated
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
Fully-constructed request to update an AlloyDB instance.
|
|
"""
|
|
instance_resource, paths = ConstructInstanceAndUpdatePathsFromArgs(
|
|
alloydb_messages, instance_ref, args, release_track=base.ReleaseTrack.GA
|
|
)
|
|
mask = ','.join(paths) if paths else None
|
|
|
|
return alloydb_messages.AlloydbProjectsLocationsClustersInstancesPatchRequest(
|
|
instance=instance_resource,
|
|
name=instance_ref.RelativeName(),
|
|
updateMask=mask,
|
|
)
|
|
|
|
|
|
def ConstructInstanceAndUpdatePathsFromArgs(
|
|
alloydb_messages, instance_ref, args, release_track=base.ReleaseTrack.GA
|
|
):
|
|
"""Validates command line arguments and creates the instance and update paths.
|
|
|
|
Args:
|
|
alloydb_messages: Messages module for the API client.
|
|
instance_ref: parent resource path of the resource being updated
|
|
args: Command line input arguments.
|
|
release_track: The release track of the gcloud client.
|
|
|
|
Returns:
|
|
An AlloyDB instance and paths for update.
|
|
"""
|
|
availability_type_path = 'availabilityType'
|
|
database_flags_path = 'databaseFlags'
|
|
cpu_count_path = 'machineConfig.cpuCount'
|
|
machine_type_path = 'machineConfig.machineType'
|
|
read_pool_node_count_path = 'readPoolConfig.nodeCount'
|
|
insights_config_query_string_length_path = (
|
|
'queryInsightsConfig.queryStringLength'
|
|
)
|
|
insights_config_query_plans_per_minute_path = (
|
|
'queryInsightsConfig.queryPlansPerMinute'
|
|
)
|
|
insights_config_record_application_tags_path = (
|
|
'queryInsightsConfig.recordApplicationTags'
|
|
)
|
|
insights_config_record_client_address_path = (
|
|
'queryInsightsConfig.recordClientAddress'
|
|
)
|
|
activation_policy_path = 'activationPolicy'
|
|
|
|
instance_resource = alloydb_messages.Instance()
|
|
paths = []
|
|
|
|
instance_resource.name = instance_ref.RelativeName()
|
|
if args.activation_policy:
|
|
instance_resource.activationPolicy = args.activation_policy
|
|
paths.append(activation_policy_path)
|
|
|
|
availability_type = ParseAvailabilityType(
|
|
alloydb_messages, args.availability_type
|
|
)
|
|
if availability_type:
|
|
instance_resource.availabilityType = availability_type
|
|
paths.append(availability_type_path)
|
|
|
|
database_flags = labels_util.ParseCreateArgs(
|
|
args,
|
|
alloydb_messages.Instance.DatabaseFlagsValue,
|
|
labels_dest='database_flags',
|
|
)
|
|
if database_flags:
|
|
instance_resource.databaseFlags = database_flags
|
|
paths.append(database_flags_path)
|
|
|
|
if args.cpu_count or args.machine_type:
|
|
instance_resource.machineConfig = alloydb_messages.MachineConfig(
|
|
cpuCount=args.cpu_count, machineType=args.machine_type
|
|
)
|
|
if args.cpu_count:
|
|
paths.append(cpu_count_path)
|
|
if args.machine_type:
|
|
paths.append(machine_type_path)
|
|
|
|
if args.read_pool_node_count:
|
|
instance_resource.readPoolConfig = alloydb_messages.ReadPoolConfig(
|
|
nodeCount=args.read_pool_node_count
|
|
)
|
|
paths.append(read_pool_node_count_path)
|
|
|
|
if args.insights_config_query_string_length:
|
|
paths.append(insights_config_query_string_length_path)
|
|
if args.insights_config_query_plans_per_minute:
|
|
paths.append(insights_config_query_plans_per_minute_path)
|
|
if args.insights_config_record_application_tags is not None:
|
|
paths.append(insights_config_record_application_tags_path)
|
|
if args.insights_config_record_client_address is not None:
|
|
paths.append(insights_config_record_client_address_path)
|
|
|
|
instance_resource.queryInsightsConfig = _QueryInsightsConfig(
|
|
alloydb_messages,
|
|
args.insights_config_query_string_length,
|
|
args.insights_config_query_plans_per_minute,
|
|
args.insights_config_record_application_tags,
|
|
args.insights_config_record_client_address,
|
|
)
|
|
|
|
# Check if require_connectors is set to True/False, then update
|
|
if args.require_connectors is not None:
|
|
require_connectors_path = 'clientConnectionConfig.requireConnectors'
|
|
paths.append(require_connectors_path)
|
|
if args.ssl_mode:
|
|
ssl_mode_path = 'clientConnectionConfig.sslConfig.sslMode'
|
|
paths.append(ssl_mode_path)
|
|
if args.require_connectors is not None or args.ssl_mode:
|
|
instance_resource.clientConnectionConfig = ClientConnectionConfig(
|
|
alloydb_messages, args.ssl_mode, args.require_connectors
|
|
)
|
|
|
|
if (
|
|
args.assign_inbound_public_ip
|
|
or args.authorized_external_networks is not None
|
|
or args.outbound_public_ip is not None
|
|
):
|
|
instance_resource.networkConfig = NetworkConfig(
|
|
alloydb_messages=alloydb_messages,
|
|
assign_inbound_public_ip=args.assign_inbound_public_ip,
|
|
authorized_external_networks=args.authorized_external_networks,
|
|
outbound_public_ip=args.outbound_public_ip,
|
|
)
|
|
if args.outbound_public_ip is not None:
|
|
outbound_public_ip_path = 'networkConfig.enableOutboundPublicIp'
|
|
paths.append(outbound_public_ip_path)
|
|
# If we are disabling public ip then update both enablePublicIp and
|
|
# authorizedExternalNetworks because we need to clear the list of authorized
|
|
# networks.
|
|
if (
|
|
args.assign_inbound_public_ip
|
|
and not instance_resource.networkConfig.enablePublicIp
|
|
):
|
|
paths.append('networkConfig.enablePublicIp')
|
|
paths.append('networkConfig.authorizedExternalNetworks')
|
|
else:
|
|
if args.assign_inbound_public_ip:
|
|
paths.append('networkConfig.enablePublicIp')
|
|
if args.authorized_external_networks is not None:
|
|
paths.append('networkConfig.authorizedExternalNetworks')
|
|
|
|
# Empty lists are allowed for consumers to remove all PSC allowed projects.
|
|
if (
|
|
args.allowed_psc_projects is not None
|
|
or args.psc_network_attachment_uri is not None
|
|
or args.clear_psc_network_attachment_uri
|
|
or args.psc_auto_connections is not None
|
|
or args.clear_psc_auto_connections
|
|
):
|
|
instance_resource.pscInstanceConfig = PscInstanceConfig(
|
|
alloydb_messages=alloydb_messages,
|
|
allowed_psc_projects=args.allowed_psc_projects,
|
|
psc_network_attachment_uri=args.psc_network_attachment_uri,
|
|
clear_psc_network_attachment_uri=args.clear_psc_network_attachment_uri,
|
|
psc_auto_connections=args.psc_auto_connections,
|
|
clear_psc_auto_connections=args.clear_psc_auto_connections,
|
|
)
|
|
if (
|
|
args.psc_network_attachment_uri is not None
|
|
or args.clear_psc_network_attachment_uri
|
|
):
|
|
paths.append('pscInstanceConfig.pscInterfaceConfigs')
|
|
if args.allowed_psc_projects is not None:
|
|
paths.append('pscInstanceConfig.allowedConsumerProjects')
|
|
if args.psc_auto_connections is not None or args.clear_psc_auto_connections:
|
|
paths.append('pscInstanceConfig.pscAutoConnections')
|
|
|
|
# We update the whole connection pool config if any of the connection pooling
|
|
# flags are set because we want to preserve any existing flags. But to do so,
|
|
# we need to check what these existing flag values are, and that requires
|
|
# calling the AlloyDB API with the same version as the gcloud release track.
|
|
#
|
|
# We also need to check that the release track is GA to avoid calling the
|
|
# GetInstance API more than need be when the Beta/Alpha versions call this
|
|
# function.
|
|
if (release_track == base.ReleaseTrack.GA and (
|
|
args.enable_connection_pooling is not None
|
|
or args.connection_pooling_pool_mode is not None
|
|
or args.connection_pooling_min_pool_size is not None
|
|
or args.connection_pooling_max_pool_size is not None
|
|
or args.connection_pooling_max_client_connections is not None
|
|
or args.connection_pooling_server_idle_timeout is not None
|
|
or args.connection_pooling_query_wait_timeout is not None
|
|
or args.connection_pooling_stats_users is not None
|
|
or args.connection_pooling_ignore_startup_parameters is not None
|
|
or args.connection_pooling_server_lifetime is not None
|
|
or args.connection_pooling_client_connection_idle_timeout is not None
|
|
or args.connection_pooling_max_prepared_statements is not None)):
|
|
paths.append('connectionPoolConfig')
|
|
|
|
instance_resource.connectionPoolConfig = _UpdateConnectionPoolConfig(
|
|
instance_ref,
|
|
release_track=release_track,
|
|
alloydb_messages=alloydb_messages,
|
|
enable_connection_pooling=args.enable_connection_pooling,
|
|
connection_pooling_pool_mode=args.connection_pooling_pool_mode,
|
|
connection_pooling_min_pool_size=args.connection_pooling_min_pool_size,
|
|
connection_pooling_max_pool_size=args.connection_pooling_max_pool_size,
|
|
connection_pooling_max_client_conn=args.connection_pooling_max_client_connections,
|
|
connection_pooling_server_idle_timeout=args.connection_pooling_server_idle_timeout,
|
|
connection_pooling_query_wait_timeout=args.connection_pooling_query_wait_timeout,
|
|
connection_pooling_stats_users=args.connection_pooling_stats_users,
|
|
connection_pooling_ignore_startup_parameters=args.connection_pooling_ignore_startup_parameters,
|
|
connection_pooling_server_lifetime=args.connection_pooling_server_lifetime,
|
|
connection_pooling_client_connection_idle_timeout=args.connection_pooling_client_connection_idle_timeout,
|
|
connection_pooling_max_prepared_statements=args.connection_pooling_max_prepared_statements,
|
|
)
|
|
|
|
return instance_resource, paths
|
|
|
|
|
|
def _QueryInsightsConfig(
|
|
alloydb_messages,
|
|
insights_config_query_string_length=None,
|
|
insights_config_query_plans_per_minute=None,
|
|
insights_config_record_application_tags=None,
|
|
insights_config_record_client_address=None,
|
|
):
|
|
"""Generates the insights config for the instance.
|
|
|
|
Args:
|
|
alloydb_messages: module, Message module for the API client.
|
|
insights_config_query_string_length: number, length of the query string to
|
|
be stored.
|
|
insights_config_query_plans_per_minute: number, number of query plans to
|
|
sample every minute.
|
|
insights_config_record_application_tags: boolean, True if application tags
|
|
should be recorded.
|
|
insights_config_record_client_address: boolean, True if client address
|
|
should be recorded.
|
|
|
|
Returns:
|
|
alloydb_messages.QueryInsightsInstanceConfig or None
|
|
"""
|
|
|
|
should_generate_config = any([
|
|
insights_config_query_string_length is not None,
|
|
insights_config_query_plans_per_minute is not None,
|
|
insights_config_record_application_tags is not None,
|
|
insights_config_record_client_address is not None,
|
|
])
|
|
if not should_generate_config:
|
|
return None
|
|
|
|
# Config exists, generate insights config.
|
|
insights_config = alloydb_messages.QueryInsightsInstanceConfig()
|
|
if insights_config_query_string_length is not None:
|
|
insights_config.queryStringLength = insights_config_query_string_length
|
|
if insights_config_query_plans_per_minute is not None:
|
|
insights_config.queryPlansPerMinute = insights_config_query_plans_per_minute
|
|
if insights_config_record_application_tags is not None:
|
|
insights_config.recordApplicationTags = (
|
|
insights_config_record_application_tags
|
|
)
|
|
if insights_config_record_client_address is not None:
|
|
insights_config.recordClientAddress = insights_config_record_client_address
|
|
|
|
return insights_config
|
|
|
|
|
|
def _ObservabilityConfig(
|
|
alloydb_messages,
|
|
observability_config_enabled=None,
|
|
observability_config_preserve_comments=None,
|
|
observability_config_track_wait_events=None,
|
|
observability_config_max_query_string_length=None,
|
|
observability_config_record_application_tags=None,
|
|
observability_config_query_plans_per_minute=None,
|
|
observability_config_track_active_queries=None,
|
|
):
|
|
"""Generates the observability config for the instance.
|
|
|
|
Args:
|
|
alloydb_messages: module, Message module for the API client.
|
|
observability_config_enabled: boolean, True if observability should be
|
|
enabled.
|
|
observability_config_preserve_comments: boolean, True if comments should be
|
|
preserved in the query string.
|
|
observability_config_track_wait_events: boolean, True if wait events should
|
|
be tracked.
|
|
observability_config_max_query_string_length: number, length of the query
|
|
string to be stored.
|
|
observability_config_record_application_tags: boolean, True if application
|
|
tags should be recorded.
|
|
observability_config_query_plans_per_minute: number, number of query plans
|
|
to sample every minute.
|
|
observability_config_track_active_queries: boolean, True if active queries
|
|
should be tracked.
|
|
|
|
Returns:
|
|
alloydb_messages.ObservabilityInstanceConfig or None
|
|
"""
|
|
|
|
should_generate_config = any([
|
|
observability_config_enabled is not None,
|
|
observability_config_preserve_comments is not None,
|
|
observability_config_track_wait_events is not None,
|
|
observability_config_max_query_string_length is not None,
|
|
observability_config_record_application_tags is not None,
|
|
observability_config_query_plans_per_minute is not None,
|
|
observability_config_track_active_queries is not None,
|
|
])
|
|
if not should_generate_config:
|
|
return None
|
|
|
|
# Config exists, generate observability config.
|
|
observability_config = alloydb_messages.ObservabilityInstanceConfig()
|
|
if observability_config_enabled is not None:
|
|
observability_config.enabled = observability_config_enabled
|
|
if observability_config_preserve_comments is not None:
|
|
observability_config.preserveComments = (
|
|
observability_config_preserve_comments
|
|
)
|
|
if observability_config_track_wait_events is not None:
|
|
observability_config.trackWaitEvents = (
|
|
observability_config_track_wait_events
|
|
)
|
|
if observability_config_max_query_string_length is not None:
|
|
observability_config.maxQueryStringLength = (
|
|
observability_config_max_query_string_length
|
|
)
|
|
if observability_config_record_application_tags is not None:
|
|
observability_config.recordApplicationTags = (
|
|
observability_config_record_application_tags
|
|
)
|
|
if observability_config_query_plans_per_minute is not None:
|
|
observability_config.queryPlansPerMinute = (
|
|
observability_config_query_plans_per_minute
|
|
)
|
|
if observability_config_track_active_queries is not None:
|
|
observability_config.trackActiveQueries = (
|
|
observability_config_track_active_queries
|
|
)
|
|
|
|
return observability_config
|
|
|
|
|
|
def ClientConnectionConfig(
|
|
alloydb_messages,
|
|
ssl_mode=None,
|
|
require_connectors=None,
|
|
):
|
|
"""Generates the client connection config for the instance.
|
|
|
|
Args:
|
|
alloydb_messages: module, Message module for the API client.
|
|
ssl_mode: string, SSL mode to use when connecting to the database.
|
|
require_connectors: boolean, whether or not to enforce connections to the
|
|
database to go through a connector (ex: Auth Proxy).
|
|
|
|
Returns:
|
|
alloydb_messages.ClientConnectionConfig
|
|
"""
|
|
|
|
should_generate_config = any([
|
|
ssl_mode is not None,
|
|
require_connectors is not None,
|
|
])
|
|
if not should_generate_config:
|
|
return None
|
|
|
|
# Config exists, generate client connection config.
|
|
client_connection_config = alloydb_messages.ClientConnectionConfig()
|
|
client_connection_config.requireConnectors = require_connectors
|
|
ssl_config = alloydb_messages.SslConfig()
|
|
# Set SSL mode if provided
|
|
ssl_config.sslMode = _ParseSSLMode(alloydb_messages, ssl_mode)
|
|
client_connection_config.sslConfig = ssl_config
|
|
|
|
return client_connection_config
|
|
|
|
|
|
def ParseAvailabilityType(alloydb_messages, availability_type):
|
|
if availability_type:
|
|
return alloydb_messages.Instance.AvailabilityTypeValueValuesEnum.lookup_by_name(
|
|
availability_type.upper()
|
|
)
|
|
return None
|
|
|
|
|
|
def ParseAutoScalingConfig(alloydb_messages, instance_ref, release_track, args):
|
|
"""Parses command line arguments and creates an AutoScalingConfig object.
|
|
|
|
Args:
|
|
alloydb_messages: Messages module for the API client.
|
|
instance_ref: A reference to the instance.
|
|
release_track: The release track of the gcloud client.
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
A fully-constructed alloydb_messages.AutoScalingConfig object.
|
|
"""
|
|
if args.enable_autoscaler is not None and not args.enable_autoscaler:
|
|
return None
|
|
auto_scaling_config = alloydb_messages.AutoScalingConfig()
|
|
if instance_ref and release_track:
|
|
client = api_util.AlloyDBClient(release_track)
|
|
alloydb_client = client.alloydb_client
|
|
req = alloydb_messages.AlloydbProjectsLocationsClustersInstancesGetRequest(
|
|
name=instance_ref.RelativeName()
|
|
)
|
|
existing_instance = (
|
|
alloydb_client.projects_locations_clusters_instances.Get(req)
|
|
)
|
|
if (
|
|
existing_instance.readPoolConfig
|
|
and existing_instance.readPoolConfig.autoScalingConfig
|
|
):
|
|
auto_scaling_config = existing_instance.readPoolConfig.autoScalingConfig
|
|
if not auto_scaling_config.policy:
|
|
auto_scaling_config.policy = alloydb_messages.Policy()
|
|
|
|
if args.autoscaler_max_node_count is not None:
|
|
auto_scaling_config.policy.maxNodeCount = args.autoscaler_max_node_count
|
|
if args.autoscaler_cool_down_period_seconds is not None:
|
|
auto_scaling_config.policy.coolDownPeriodSec = (
|
|
args.autoscaler_cool_down_period_seconds
|
|
)
|
|
if not auto_scaling_config.policy.cpuUtilization:
|
|
auto_scaling_config.policy.cpuUtilization = (
|
|
alloydb_messages.CpuUtilization()
|
|
)
|
|
if args.autoscaler_target_cpu_usage is not None:
|
|
auto_scaling_config.policy.cpuUtilization.utilizationTarget = (
|
|
args.autoscaler_target_cpu_usage
|
|
)
|
|
if args.enable_autoscaler is not None:
|
|
auto_scaling_config.policy.enabled = (
|
|
args.enable_autoscaler or auto_scaling_config.policy.enabled
|
|
)
|
|
if instance_ref:
|
|
# Deleting, disabling, and enabling schedules are only for the update
|
|
# command.
|
|
if args.autoscaler_delete_schedule is not None:
|
|
new_schedules = []
|
|
for schedule in auto_scaling_config.schedules:
|
|
if schedule.name != args.autoscaler_delete_schedule:
|
|
new_schedules.append(schedule)
|
|
auto_scaling_config.schedules = new_schedules
|
|
if args.autoscaler_disable_schedule is not None:
|
|
new_schedules = []
|
|
for schedule in auto_scaling_config.schedules:
|
|
if schedule.name == args.autoscaler_disable_schedule:
|
|
schedule.disabled = True
|
|
new_schedules.append(schedule)
|
|
auto_scaling_config.schedules = new_schedules
|
|
if args.autoscaler_enable_schedule is not None:
|
|
new_schedules = []
|
|
for schedule in auto_scaling_config.schedules:
|
|
if schedule.name == args.autoscaler_enable_schedule:
|
|
schedule.disabled = False
|
|
new_schedules.append(schedule)
|
|
auto_scaling_config.schedules = new_schedules
|
|
if args.autoscaler_set_schedule is not None:
|
|
is_new_schedule = True
|
|
schedule = alloydb_messages.Schedule()
|
|
schedule.name = args.autoscaler_set_schedule
|
|
for s in auto_scaling_config.schedules:
|
|
if s.name == args.autoscaler_set_schedule:
|
|
schedule = s
|
|
is_new_schedule = False
|
|
break
|
|
if args.autoscaler_schedule_cron_exp is not None:
|
|
schedule.cronExpression = args.autoscaler_schedule_cron_exp
|
|
if args.autoscaler_schedule_duration_seconds is not None:
|
|
schedule.durationSec = args.autoscaler_schedule_duration_seconds
|
|
if args.autoscaler_schedule_min_node_count is not None:
|
|
schedule.minNodeCount = args.autoscaler_schedule_min_node_count
|
|
if args.autoscaler_schedule_time_zone is not None:
|
|
schedule.timeZone = args.autoscaler_schedule_time_zone
|
|
if args.autoscaler_schedule_description is not None:
|
|
schedule.description = args.autoscaler_schedule_description
|
|
if is_new_schedule:
|
|
auto_scaling_config.schedules.append(schedule)
|
|
return auto_scaling_config
|
|
|
|
|
|
def _ParseInstanceType(alloydb_messages, instance_type):
|
|
if instance_type:
|
|
return alloydb_messages.Instance.InstanceTypeValueValuesEnum.lookup_by_name(
|
|
instance_type.upper()
|
|
)
|
|
return None
|
|
|
|
|
|
def _ParseUpdateMode(alloydb_messages, update_mode):
|
|
if update_mode:
|
|
return alloydb_messages.UpdatePolicy.ModeValueValuesEnum.lookup_by_name(
|
|
update_mode.upper()
|
|
)
|
|
return None
|
|
|
|
|
|
def _ParseSSLMode(alloydb_messages, ssl_mode):
|
|
if ssl_mode == 'ENCRYPTED_ONLY':
|
|
return alloydb_messages.SslConfig.SslModeValueValuesEnum.ENCRYPTED_ONLY
|
|
elif ssl_mode == 'ALLOW_UNENCRYPTED_AND_ENCRYPTED':
|
|
return (
|
|
alloydb_messages.SslConfig.SslModeValueValuesEnum.ALLOW_UNENCRYPTED_AND_ENCRYPTED
|
|
)
|
|
return None
|
|
|
|
|
|
def _ParsePoolMode(alloydb_messages, pool_mode):
|
|
if pool_mode == 'TRANSACTION':
|
|
return (
|
|
alloydb_messages.ConnectionPoolConfig.PoolModeValueValuesEnum.POOL_MODE_TRANSACTION
|
|
)
|
|
elif pool_mode == 'SESSION':
|
|
return (
|
|
alloydb_messages.ConnectionPoolConfig.PoolModeValueValuesEnum.POOL_MODE_SESSION
|
|
)
|
|
return None
|
|
|
|
|
|
def NetworkConfig(**kwargs):
|
|
"""Generates the network config for the instance."""
|
|
assign_inbound_public_ip = kwargs.get('assign_inbound_public_ip')
|
|
authorized_external_networks = kwargs.get('authorized_external_networks')
|
|
alloydb_messages = kwargs.get('alloydb_messages')
|
|
outbound_public_ip = kwargs.get('outbound_public_ip')
|
|
allocated_ip_range_override = kwargs.get('allocated_ip_range_override')
|
|
|
|
should_generate_config = any([
|
|
assign_inbound_public_ip,
|
|
outbound_public_ip is not None,
|
|
authorized_external_networks is not None,
|
|
allocated_ip_range_override is not None,
|
|
])
|
|
if not should_generate_config:
|
|
return None
|
|
|
|
# Config exists, generate instance network config.
|
|
instance_network_config = alloydb_messages.InstanceNetworkConfig()
|
|
|
|
if assign_inbound_public_ip:
|
|
instance_network_config.enablePublicIp = _ParseAssignInboundPublicIp(
|
|
assign_inbound_public_ip
|
|
)
|
|
if outbound_public_ip is not None:
|
|
instance_network_config.enableOutboundPublicIp = outbound_public_ip
|
|
if authorized_external_networks is not None:
|
|
if (
|
|
assign_inbound_public_ip is not None
|
|
and not instance_network_config.enablePublicIp
|
|
):
|
|
raise DetailedArgumentError(
|
|
"Cannot update an instance's authorized "
|
|
'networks and disable Public-IP. You must do '
|
|
'one or the other. Note, that disabling '
|
|
'Public-IP will clear the list of authorized '
|
|
'networks.'
|
|
)
|
|
instance_network_config.authorizedExternalNetworks = (
|
|
_ParseAuthorizedExternalNetworks(
|
|
alloydb_messages,
|
|
authorized_external_networks,
|
|
instance_network_config.enablePublicIp,
|
|
)
|
|
)
|
|
|
|
if allocated_ip_range_override is not None:
|
|
instance_network_config.allocatedIpRangeOverride = (
|
|
allocated_ip_range_override
|
|
)
|
|
return instance_network_config
|
|
|
|
|
|
def _ConnectionPoolConfig(**kwargs):
|
|
"""Generates the connection pooling config for the instance."""
|
|
enable_connection_pooling = kwargs.get('enable_connection_pooling')
|
|
if not enable_connection_pooling:
|
|
return None
|
|
|
|
pool_mode = kwargs.get('connection_pooling_pool_mode')
|
|
min_pool_size = kwargs.get('connection_pooling_min_pool_size')
|
|
default_pool_size = kwargs.get('connection_pooling_max_pool_size')
|
|
max_client_conn = kwargs.get('connection_pooling_max_client_conn')
|
|
server_idle_timeout = kwargs.get('connection_pooling_server_idle_timeout')
|
|
query_wait_timeout = kwargs.get('connection_pooling_query_wait_timeout')
|
|
stats_users = kwargs.get('connection_pooling_stats_users')
|
|
ignore_startup_parameters = kwargs.get(
|
|
'connection_pooling_ignore_startup_parameters'
|
|
)
|
|
server_lifetime = kwargs.get(
|
|
'connection_pooling_server_lifetime'
|
|
)
|
|
client_connection_idle_timeout = kwargs.get(
|
|
'connection_pooling_client_connection_idle_timeout'
|
|
)
|
|
max_prepared_statements = kwargs.get(
|
|
'connection_pooling_max_prepared_statements'
|
|
)
|
|
|
|
alloydb_messages = kwargs.get('alloydb_messages')
|
|
config = alloydb_messages.ConnectionPoolConfig()
|
|
config.enabled = enable_connection_pooling
|
|
flags = {}
|
|
if pool_mode is not None:
|
|
flags['pool_mode'] = pool_mode.lower()
|
|
if min_pool_size is not None:
|
|
flags['min_pool_size'] = min_pool_size
|
|
if default_pool_size is not None:
|
|
flags['max_pool_size'] = default_pool_size
|
|
if max_client_conn is not None:
|
|
flags['max_client_connections'] = max_client_conn
|
|
if server_idle_timeout is not None:
|
|
flags['server_connection_idle_timeout'] = server_idle_timeout
|
|
if query_wait_timeout is not None:
|
|
flags['query_wait_timeout'] = query_wait_timeout
|
|
if stats_users is not None:
|
|
flags['stats_users'] = ','.join(stats_users)
|
|
if ignore_startup_parameters is not None:
|
|
flags['ignore_startup_parameters'] = ','.join(ignore_startup_parameters)
|
|
if server_lifetime is not None:
|
|
flags['server_lifetime'] = server_lifetime
|
|
if client_connection_idle_timeout is not None:
|
|
flags['client_connection_idle_timeout'] = (
|
|
client_connection_idle_timeout
|
|
)
|
|
if max_prepared_statements is not None:
|
|
flags['max_prepared_statements'] = str(max_prepared_statements)
|
|
|
|
config.flags = alloydb_messages.ConnectionPoolConfig.FlagsValue(
|
|
additionalProperties=[
|
|
alloydb_messages.ConnectionPoolConfig.FlagsValue.AdditionalProperty(
|
|
key=key, value=value
|
|
)
|
|
for key, value in flags.items()
|
|
]
|
|
)
|
|
return config
|
|
|
|
|
|
def _UpdateConnectionPoolConfig(instance_ref, release_track, **kwargs):
|
|
"""Updates the connection pooling config for the instance.
|
|
|
|
Args:
|
|
instance_ref: A reference to the instance to be updated.
|
|
release_track: The release track of the gcloud client.
|
|
**kwargs: A map of the managed connection pooling flags and their values to
|
|
be updated.
|
|
|
|
Returns:
|
|
alloydb_messages.ConnectionPoolConfig
|
|
"""
|
|
enable_connection_pooling = kwargs.get('enable_connection_pooling')
|
|
pool_mode = kwargs.get('connection_pooling_pool_mode')
|
|
min_pool_size = kwargs.get('connection_pooling_min_pool_size')
|
|
default_pool_size = kwargs.get('connection_pooling_max_pool_size')
|
|
max_client_conn = kwargs.get('connection_pooling_max_client_conn')
|
|
server_idle_timeout = kwargs.get('connection_pooling_server_idle_timeout')
|
|
query_wait_timeout = kwargs.get('connection_pooling_query_wait_timeout')
|
|
stats_users = kwargs.get('connection_pooling_stats_users')
|
|
ignore_startup_parameters = kwargs.get(
|
|
'connection_pooling_ignore_startup_parameters'
|
|
)
|
|
server_lifetime = kwargs.get(
|
|
'connection_pooling_server_lifetime'
|
|
)
|
|
client_connection_idle_timeout = kwargs.get(
|
|
'connection_pooling_client_connection_idle_timeout'
|
|
)
|
|
max_prepared_statements = kwargs.get(
|
|
'connection_pooling_max_prepared_statements'
|
|
)
|
|
alloydb_messages = kwargs.get('alloydb_messages')
|
|
|
|
should_update_config = any([
|
|
enable_connection_pooling is not None,
|
|
pool_mode is not None,
|
|
min_pool_size is not None,
|
|
default_pool_size is not None,
|
|
max_client_conn is not None,
|
|
server_idle_timeout is not None,
|
|
query_wait_timeout is not None,
|
|
stats_users is not None,
|
|
ignore_startup_parameters is not None,
|
|
server_lifetime is not None,
|
|
client_connection_idle_timeout is not None,
|
|
max_prepared_statements is not None,
|
|
])
|
|
if not should_update_config:
|
|
return None
|
|
|
|
config = alloydb_messages.ConnectionPoolConfig()
|
|
flags = {}
|
|
|
|
# Disabling managed connection pooling should set all other connection pooling
|
|
# settings to None.
|
|
if not enable_connection_pooling and enable_connection_pooling is not None:
|
|
config.enabled = False
|
|
return config
|
|
|
|
# Build the connection pooling config based on the existing values that are
|
|
# set in the instance, if they aren't specified in the update. If the flag
|
|
# is set in the update, it will override the existing value. We use the same
|
|
# AlloyDB API version as the gcloud version the update request is coming from.
|
|
client = api_util.AlloyDBClient(release_track)
|
|
alloydb_client = client.alloydb_client
|
|
req = alloydb_messages.AlloydbProjectsLocationsClustersInstancesGetRequest(
|
|
name=instance_ref.RelativeName()
|
|
)
|
|
existing_instance = alloydb_client.projects_locations_clusters_instances.Get(
|
|
req
|
|
)
|
|
has_existing_config = existing_instance.connectionPoolConfig is not None
|
|
if (
|
|
has_existing_config
|
|
and existing_instance.connectionPoolConfig.flags is not None
|
|
):
|
|
flag_names = [
|
|
'pool_mode',
|
|
'min_pool_size',
|
|
'max_pool_size',
|
|
'max_client_connections',
|
|
'server_connection_idle_timeout',
|
|
'query_wait_timeout',
|
|
'stats_users',
|
|
'ignore_startup_parameters',
|
|
'server_lifetime',
|
|
'client_connection_idle_timeout',
|
|
'max_prepared_statements'
|
|
]
|
|
for f in flag_names:
|
|
exists, value = _CheckIfConnectionPoolConfigFlagExists(
|
|
existing_instance, f
|
|
)
|
|
if exists:
|
|
flags[f] = value
|
|
|
|
if enable_connection_pooling is not None:
|
|
config.enabled = enable_connection_pooling
|
|
elif has_existing_config:
|
|
config.enabled = existing_instance.connectionPoolConfig.enabled
|
|
|
|
if pool_mode is not None:
|
|
flags['pool_mode'] = pool_mode.lower()
|
|
if min_pool_size is not None:
|
|
flags['min_pool_size'] = min_pool_size
|
|
if default_pool_size is not None:
|
|
flags['max_pool_size'] = default_pool_size
|
|
if max_client_conn is not None:
|
|
flags['max_client_connections'] = max_client_conn
|
|
if server_idle_timeout is not None:
|
|
flags['server_connection_idle_timeout'] = server_idle_timeout
|
|
if query_wait_timeout is not None:
|
|
flags['query_wait_timeout'] = query_wait_timeout
|
|
if stats_users is not None:
|
|
flags['stats_users'] = ','.join(stats_users)
|
|
if ignore_startup_parameters is not None:
|
|
flags['ignore_startup_parameters'] = ','.join(ignore_startup_parameters)
|
|
if server_lifetime is not None:
|
|
flags['server_lifetime'] = server_lifetime
|
|
if client_connection_idle_timeout is not None:
|
|
flags['client_connection_idle_timeout'] = client_connection_idle_timeout
|
|
if max_prepared_statements is not None:
|
|
flags['max_prepared_statements'] = str(max_prepared_statements)
|
|
|
|
config.flags = alloydb_messages.ConnectionPoolConfig.FlagsValue(
|
|
additionalProperties=[
|
|
alloydb_messages.ConnectionPoolConfig.FlagsValue.AdditionalProperty(
|
|
key=key, value=value
|
|
)
|
|
for key, value in flags.items()
|
|
]
|
|
)
|
|
return config
|
|
|
|
|
|
def _CheckIfConnectionPoolConfigFlagExists(instance, flag_name):
|
|
"""Checks if a flag exists in the instance's connection pool config.
|
|
|
|
Args:
|
|
instance: The existing instance to check against.
|
|
flag_name: The name of the flag to check if it exists in the instance.
|
|
|
|
Returns:
|
|
True and the value of the flag if the flag exists, False otherwise.
|
|
|
|
"""
|
|
if instance.connectionPoolConfig.flags.additionalProperties is None:
|
|
return False, None
|
|
for prop in instance.connectionPoolConfig.flags.additionalProperties:
|
|
if prop.key == flag_name:
|
|
return True, prop.value
|
|
return False, None
|
|
|
|
|
|
def PscInstanceConfig(**kwargs):
|
|
"""Generates the PSC instance config for the instance."""
|
|
alloydb_messages = kwargs.get('alloydb_messages')
|
|
allowed_psc_projects = kwargs.get('allowed_psc_projects')
|
|
psc_network_attachment_uri = kwargs.get('psc_network_attachment_uri')
|
|
clear_psc_network_attachment_uri = kwargs.get(
|
|
'clear_psc_network_attachment_uri'
|
|
)
|
|
psc_auto_connections = kwargs.get('psc_auto_connections')
|
|
clear_psc_auto_connections = kwargs.get('clear_psc_auto_connections')
|
|
|
|
psc_instance_config = alloydb_messages.PscInstanceConfig()
|
|
if allowed_psc_projects:
|
|
psc_instance_config.allowedConsumerProjects = allowed_psc_projects
|
|
if clear_psc_network_attachment_uri:
|
|
psc_instance_config.pscInterfaceConfigs = []
|
|
elif psc_network_attachment_uri is not None:
|
|
psc_instance_config.pscInterfaceConfigs.append(
|
|
_PscInterfaceConfig(
|
|
alloydb_messages=alloydb_messages,
|
|
psc_network_attachment_uri=psc_network_attachment_uri,
|
|
)
|
|
)
|
|
if clear_psc_auto_connections:
|
|
psc_instance_config.pscAutoConnections = []
|
|
elif psc_auto_connections is not None:
|
|
psc_instance_config.pscAutoConnections = _PscAutoConnections(
|
|
alloydb_messages=alloydb_messages,
|
|
psc_auto_connections=psc_auto_connections,
|
|
)
|
|
|
|
return psc_instance_config
|
|
|
|
|
|
def _PscInterfaceConfig(
|
|
alloydb_messages,
|
|
psc_network_attachment_uri=None,
|
|
):
|
|
"""Generates the PSC interface config for the instance."""
|
|
psc_interface_config = alloydb_messages.PscInterfaceConfig()
|
|
psc_interface_config.networkAttachmentResource = psc_network_attachment_uri
|
|
return psc_interface_config
|
|
|
|
|
|
def _PscAutoConnections(
|
|
alloydb_messages,
|
|
psc_auto_connections=None,
|
|
):
|
|
"""Generates the PSC auto connections for the instance."""
|
|
out_psc_auto_connections = []
|
|
for connection in psc_auto_connections:
|
|
config = alloydb_messages.PscAutoConnectionConfig()
|
|
config.consumerProject = connection.get('project')
|
|
config.consumerNetwork = connection.get('network')
|
|
|
|
if config.consumerProject and config.consumerNetwork:
|
|
out_psc_auto_connections.append(config)
|
|
else:
|
|
raise DetailedArgumentError(
|
|
'Invalid PSC auto connection. Please provide both project and network'
|
|
' for the PSC auto connection.'
|
|
)
|
|
return out_psc_auto_connections
|
|
|
|
|
|
def _ParseAssignInboundPublicIp(assign_inbound_public_ip):
|
|
"""Parses the assign_inbound_public_ip flag.
|
|
|
|
Args:
|
|
assign_inbound_public_ip: string, the Public-IP mode to use.
|
|
|
|
Returns:
|
|
boolean, whether or not Public-IP is enabled.
|
|
|
|
Raises:
|
|
ValueError if try to use any other value besides NO_PUBLIC_IP during
|
|
instance creation, or if use an unrecognized argument.
|
|
"""
|
|
if assign_inbound_public_ip == 'NO_PUBLIC_IP':
|
|
return False
|
|
if assign_inbound_public_ip == 'ASSIGN_IPV4':
|
|
return True
|
|
raise DetailedArgumentError(
|
|
'Unrecognized argument. Please use NO_PUBLIC_IP or ASSIGN_IPV4.'
|
|
)
|
|
|
|
|
|
def _ParseAuthorizedExternalNetworks(
|
|
alloydb_messages, authorized_external_networks, public_ip_enabled
|
|
):
|
|
"""Parses the authorized_external_networks flag.
|
|
|
|
Args:
|
|
alloydb_messages: Messages module for the API client.
|
|
authorized_external_networks: list, list of authorized networks.
|
|
public_ip_enabled: boolean, whether or not Public-IP is enabled.
|
|
|
|
Returns:
|
|
list of alloydb_messages.AuthorizedNetwork
|
|
"""
|
|
auth_networks = []
|
|
if public_ip_enabled is not None and not public_ip_enabled:
|
|
return auth_networks
|
|
for network in authorized_external_networks:
|
|
network = alloydb_messages.AuthorizedNetwork(cidrRange=str(network))
|
|
auth_networks.append(network)
|
|
return auth_networks
|
|
|
|
|
|
def ConstructPatchRequestFromArgsBeta(alloydb_messages, instance_ref, args):
|
|
"""Constructs the request to update an AlloyDB instance."""
|
|
instance_resource, paths = ConstructInstanceAndUpdatePathsFromArgsBeta(
|
|
alloydb_messages, instance_ref, args,
|
|
release_track=base.ReleaseTrack.BETA,
|
|
)
|
|
mask = ','.join(paths) if paths else None
|
|
|
|
return alloydb_messages.AlloydbProjectsLocationsClustersInstancesPatchRequest(
|
|
instance=instance_resource,
|
|
name=instance_ref.RelativeName(),
|
|
updateMask=mask,
|
|
)
|
|
|
|
|
|
def ConstructPatchRequestFromArgsAlpha(alloydb_messages, instance_ref, args):
|
|
"""Constructs the request to update an AlloyDB instance."""
|
|
instance_resource, paths = ConstructInstanceAndUpdatePathsFromArgsAlpha(
|
|
alloydb_messages, instance_ref, args,
|
|
release_track=base.ReleaseTrack.ALPHA,
|
|
)
|
|
|
|
mask = ','.join(paths) if paths else None
|
|
|
|
return alloydb_messages.AlloydbProjectsLocationsClustersInstancesPatchRequest(
|
|
instance=instance_resource,
|
|
name=instance_ref.RelativeName(),
|
|
updateMask=mask,
|
|
)
|
|
|
|
|
|
def ConstructInstanceAndUpdatePathsFromArgsBeta(
|
|
alloydb_messages, instance_ref, args, release_track
|
|
):
|
|
"""Validates command line arguments and creates the instance and update paths for beta track.
|
|
|
|
Args:
|
|
alloydb_messages: Messages module for the API client.
|
|
instance_ref: parent resource path of the resource being updated
|
|
args: Command line input arguments.
|
|
release_track: The release track of the gcloud client.
|
|
|
|
Returns:
|
|
An AlloyDB instance and paths for update.
|
|
"""
|
|
observability_config_enabled_path = 'observabilityConfig.enabled'
|
|
observability_config_preserve_comments_path = (
|
|
'observabilityConfig.preserveComments'
|
|
)
|
|
observability_config_track_wait_events_path = (
|
|
'observabilityConfig.trackWaitEvents'
|
|
)
|
|
observability_config_max_query_string_length_path = (
|
|
'observabilityConfig.maxQueryStringLength'
|
|
)
|
|
observability_config_record_application_tags_path = (
|
|
'observabilityConfig.recordApplicationTags'
|
|
)
|
|
observability_config_query_plans_per_minute_path = (
|
|
'observabilityConfig.queryPlansPerMinute'
|
|
)
|
|
observability_config_track_active_queries_path = (
|
|
'observabilityConfig.trackActiveQueries'
|
|
)
|
|
instance_resource, paths = ConstructInstanceAndUpdatePathsFromArgs(
|
|
alloydb_messages, instance_ref, args, release_track
|
|
)
|
|
|
|
if args.update_mode:
|
|
instance_resource.updatePolicy = alloydb_messages.UpdatePolicy(
|
|
mode=_ParseUpdateMode(alloydb_messages, args.update_mode)
|
|
)
|
|
update_mode_path = 'updatePolicy.mode'
|
|
paths.append(update_mode_path)
|
|
if args.observability_config_enabled is not None:
|
|
paths.append(observability_config_enabled_path)
|
|
if args.observability_config_preserve_comments is not None:
|
|
paths.append(observability_config_preserve_comments_path)
|
|
if args.observability_config_track_wait_events is not None:
|
|
paths.append(observability_config_track_wait_events_path)
|
|
if args.observability_config_max_query_string_length is not None:
|
|
paths.append(observability_config_max_query_string_length_path)
|
|
if args.observability_config_record_application_tags is not None:
|
|
paths.append(observability_config_record_application_tags_path)
|
|
if args.observability_config_query_plans_per_minute is not None:
|
|
paths.append(observability_config_query_plans_per_minute_path)
|
|
if args.observability_config_track_active_queries is not None:
|
|
paths.append(observability_config_track_active_queries_path)
|
|
|
|
instance_resource.observabilityConfig = _ObservabilityConfig(
|
|
alloydb_messages,
|
|
args.observability_config_enabled,
|
|
args.observability_config_preserve_comments,
|
|
args.observability_config_track_wait_events,
|
|
args.observability_config_max_query_string_length,
|
|
args.observability_config_record_application_tags,
|
|
args.observability_config_query_plans_per_minute,
|
|
args.observability_config_track_active_queries,
|
|
)
|
|
|
|
# We update the whole connection pool config if any of the connection pooling
|
|
# flags are set because we want to preserve any existing flags. But to do so,
|
|
# we need to check what these existing flag values are, and that requires
|
|
# calling the AlloyDB API with the same version as the gcloud release track.
|
|
#
|
|
# We also need to check that the release track is Beta to avoid calling the
|
|
# GetInstance API more than need be when the Alpha versions call this
|
|
# function.
|
|
if (release_track == base.ReleaseTrack.BETA and (
|
|
args.enable_connection_pooling is not None
|
|
or args.connection_pooling_pool_mode is not None
|
|
or args.connection_pooling_min_pool_size is not None
|
|
or args.connection_pooling_max_pool_size is not None
|
|
or args.connection_pooling_max_client_connections is not None
|
|
or args.connection_pooling_server_idle_timeout is not None
|
|
or args.connection_pooling_query_wait_timeout is not None
|
|
or args.connection_pooling_stats_users is not None
|
|
or args.connection_pooling_ignore_startup_parameters is not None
|
|
or args.connection_pooling_server_lifetime is not None
|
|
or args.connection_pooling_client_connection_idle_timeout is not None
|
|
or args.connection_pooling_max_prepared_statements is not None)):
|
|
paths.append('connectionPoolConfig')
|
|
|
|
instance_resource.connectionPoolConfig = _UpdateConnectionPoolConfig(
|
|
instance_ref,
|
|
release_track=release_track,
|
|
alloydb_messages=alloydb_messages,
|
|
enable_connection_pooling=args.enable_connection_pooling,
|
|
connection_pooling_pool_mode=args.connection_pooling_pool_mode,
|
|
connection_pooling_min_pool_size=args.connection_pooling_min_pool_size,
|
|
connection_pooling_max_pool_size=args.connection_pooling_max_pool_size,
|
|
connection_pooling_max_client_conn=args.connection_pooling_max_client_connections,
|
|
connection_pooling_server_idle_timeout=args.connection_pooling_server_idle_timeout,
|
|
connection_pooling_query_wait_timeout=args.connection_pooling_query_wait_timeout,
|
|
connection_pooling_stats_users=args.connection_pooling_stats_users,
|
|
connection_pooling_ignore_startup_parameters=args.connection_pooling_ignore_startup_parameters,
|
|
connection_pooling_server_lifetime=args.connection_pooling_server_lifetime,
|
|
connection_pooling_client_connection_idle_timeout=args.connection_pooling_client_connection_idle_timeout,
|
|
connection_pooling_max_prepared_statements=args.connection_pooling_max_prepared_statements,
|
|
)
|
|
|
|
if (
|
|
args.autoscaler_max_node_count is not None
|
|
or args.autoscaler_cool_down_period_seconds is not None
|
|
or args.autoscaler_target_cpu_usage is not None
|
|
or args.enable_autoscaler is not None
|
|
or args.autoscaler_delete_schedule is not None
|
|
or args.autoscaler_set_schedule is not None
|
|
or args.autoscaler_schedule_cron_exp is not None
|
|
or args.autoscaler_schedule_duration_seconds is not None
|
|
or args.autoscaler_schedule_min_node_count is not None
|
|
or args.autoscaler_schedule_time_zone is not None
|
|
or args.autoscaler_disable_schedule is not None
|
|
or args.autoscaler_enable_schedule is not None
|
|
or args.autoscaler_schedule_description is not None
|
|
):
|
|
auto_scaling_config = ParseAutoScalingConfig(
|
|
alloydb_messages, instance_ref, release_track, args
|
|
)
|
|
if not instance_resource.readPoolConfig:
|
|
instance_resource.readPoolConfig = alloydb_messages.ReadPoolConfig()
|
|
instance_resource.readPoolConfig.autoScalingConfig = auto_scaling_config
|
|
paths.append('readPoolConfig.autoScalingConfig')
|
|
|
|
return instance_resource, paths
|
|
|
|
|
|
def ConstructInstanceAndUpdatePathsFromArgsAlpha(
|
|
alloydb_messages, instance_ref, args, release_track=base.ReleaseTrack.ALPHA
|
|
):
|
|
"""Validates command line arguments and creates the instance and update paths for alpha track.
|
|
|
|
Args:
|
|
alloydb_messages: Messages module for the API client.
|
|
instance_ref: parent resource path of the resource being updated
|
|
args: Command line input arguments.
|
|
release_track: The release track of the gcloud client.
|
|
|
|
Returns:
|
|
An AlloyDB instance and paths for update.
|
|
"""
|
|
instance_resource, paths = ConstructInstanceAndUpdatePathsFromArgsBeta(
|
|
alloydb_messages, instance_ref, args, release_track
|
|
)
|
|
|
|
# We update the whole connection pool config if any of the connection pooling
|
|
# flags are set because we want to preserve any existing flags. But to do so,
|
|
# we need to check what these existing flag values are, and that requires
|
|
# calling the AlloyDB API with the same version as the gcloud release track.
|
|
if (args.enable_connection_pooling is not None
|
|
or args.connection_pooling_pool_mode is not None
|
|
or args.connection_pooling_min_pool_size is not None
|
|
or args.connection_pooling_max_pool_size is not None
|
|
or args.connection_pooling_max_client_connections is not None
|
|
or args.connection_pooling_server_idle_timeout is not None
|
|
or args.connection_pooling_query_wait_timeout is not None
|
|
or args.connection_pooling_stats_users is not None
|
|
or args.connection_pooling_ignore_startup_parameters is not None
|
|
or args.connection_pooling_server_lifetime is not None
|
|
or args.connection_pooling_client_connection_idle_timeout is not None
|
|
or args.connection_pooling_max_prepared_statements is not None):
|
|
paths.append('connectionPoolConfig')
|
|
|
|
instance_resource.connectionPoolConfig = _UpdateConnectionPoolConfig(
|
|
instance_ref,
|
|
release_track=release_track,
|
|
alloydb_messages=alloydb_messages,
|
|
enable_connection_pooling=args.enable_connection_pooling,
|
|
connection_pooling_pool_mode=args.connection_pooling_pool_mode,
|
|
connection_pooling_min_pool_size=args.connection_pooling_min_pool_size,
|
|
connection_pooling_max_pool_size=args.connection_pooling_max_pool_size,
|
|
connection_pooling_max_client_conn=args.connection_pooling_max_client_connections,
|
|
connection_pooling_server_idle_timeout=args.connection_pooling_server_idle_timeout,
|
|
connection_pooling_query_wait_timeout=args.connection_pooling_query_wait_timeout,
|
|
connection_pooling_stats_users=args.connection_pooling_stats_users,
|
|
connection_pooling_ignore_startup_parameters=args.connection_pooling_ignore_startup_parameters,
|
|
connection_pooling_server_lifetime=args.connection_pooling_server_lifetime,
|
|
connection_pooling_client_connection_idle_timeout=args.connection_pooling_client_connection_idle_timeout,
|
|
connection_pooling_max_prepared_statements=args.connection_pooling_max_prepared_statements,
|
|
)
|
|
return instance_resource, paths
|
|
|
|
|
|
def ConstructRestartRequestFromArgs(alloydb_messages, project_ref, args):
|
|
"""Constructs the request to restart an AlloyDB instance.
|
|
|
|
Args:
|
|
alloydb_messages: Messages module for the API client.
|
|
project_ref: parent resource path of the resource being updated
|
|
args: Command line input arguments.
|
|
|
|
Returns:
|
|
Fully-constructed request to restart an AlloyDB instance.
|
|
"""
|
|
req = (
|
|
alloydb_messages.AlloydbProjectsLocationsClustersInstancesRestartRequest(
|
|
name=project_ref.RelativeName(),
|
|
)
|
|
)
|
|
if args.node_ids:
|
|
restart_request = alloydb_messages.RestartInstanceRequest(
|
|
nodeIds=args.node_ids
|
|
)
|
|
req.restartInstanceRequest = restart_request
|
|
return req
|