639 lines
17 KiB
Python
639 lines
17 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.
|
|
"""Helpers for flags in commands working with Anthos Multi-Cloud on AWS."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
from googlecloudsdk.api_lib.container.gkemulticloud import util as api_util
|
|
from googlecloudsdk.calliope import arg_parsers
|
|
from googlecloudsdk.command_lib.util.apis import arg_utils
|
|
|
|
|
|
def AddAwsRegion(parser):
|
|
parser.add_argument(
|
|
'--aws-region', required=True, help='AWS region to deploy the cluster.'
|
|
)
|
|
|
|
|
|
def GetAwsRegion(args):
|
|
return getattr(args, 'aws_region', None)
|
|
|
|
|
|
def AddVpcId(parser):
|
|
parser.add_argument(
|
|
'--vpc-id', required=True, help='VPC associated with the cluster.'
|
|
)
|
|
|
|
|
|
def GetVpcId(args):
|
|
return getattr(args, 'vpc_id', None)
|
|
|
|
|
|
def AddIamInstanceProfile(parser, kind='cluster', required=True):
|
|
"""Adds the --iam-instance-profile flag."""
|
|
parser.add_argument(
|
|
'--iam-instance-profile',
|
|
required=required,
|
|
help=(
|
|
'Name or ARN of the IAM instance profile associated with the {}.'
|
|
.format(kind)
|
|
),
|
|
)
|
|
|
|
|
|
def GetIamInstanceProfile(args):
|
|
return getattr(args, 'iam_instance_profile', None)
|
|
|
|
|
|
def AddInstanceType(parser, kind='control plane'):
|
|
"""Adds the --instance-type flag."""
|
|
parser.add_argument(
|
|
'--instance-type',
|
|
help="AWS EC2 instance type for the {}'s nodes.".format(kind),
|
|
)
|
|
|
|
|
|
def GetInstanceType(args):
|
|
return getattr(args, 'instance_type', None)
|
|
|
|
|
|
def AddSpotInstanceTypes(parser, kind='node pool'):
|
|
"""Adds the --spot-instance-types flag."""
|
|
parser.add_argument(
|
|
'--spot-instance-types',
|
|
type=arg_parsers.ArgList(),
|
|
metavar='INSTANCE_TYPE',
|
|
help=(
|
|
"List of AWS EC2 instance types for creating a spot {}'s nodes. The"
|
|
' specified instance types must have the same CPU architecture, the'
|
|
' same number of CPUs and memory. You can use the Amazon EC2 Instance'
|
|
' Selector tool (https://github.com/aws/amazon-ec2-instance-selector)'
|
|
' to choose instance types with matching CPU and memory'
|
|
' configurations.'.format(kind)
|
|
),
|
|
)
|
|
|
|
|
|
def AddOnDemandOrSpotInstanceType(parser, kind='node pool'):
|
|
"""Adds instance configurtion for creating node pool."""
|
|
group = parser.add_group('Node pool instance configuration', mutex=True)
|
|
AddInstanceType(group, kind)
|
|
AddSpotInstanceTypes(group, kind)
|
|
|
|
|
|
def GetSpotInstanceTypes(args):
|
|
return getattr(args, 'spot_instance_types', None)
|
|
|
|
|
|
def AddSshEC2KeyPair(parser, kind='control plane'):
|
|
"""Adds the --ssh-ec2-key-pair flag."""
|
|
parser.add_argument(
|
|
'--ssh-ec2-key-pair',
|
|
help=(
|
|
"Name of the EC2 key pair authorized to login to the {}'s nodes."
|
|
.format(kind)
|
|
),
|
|
)
|
|
|
|
|
|
def GetSshEC2KeyPair(args):
|
|
return getattr(args, 'ssh_ec2_key_pair', None)
|
|
|
|
|
|
def AddClearSshEc2KeyPair(parser, kind):
|
|
"""Adds the --clear-ssh-ec2-key-pair flag."""
|
|
parser.add_argument(
|
|
'--clear-ssh-ec2-key-pair',
|
|
action='store_true',
|
|
default=None,
|
|
help=(
|
|
"Clear the EC2 key pair authorized to login to the {}'s nodes."
|
|
.format(kind)
|
|
),
|
|
)
|
|
|
|
|
|
def AddSshEC2KeyPairForUpdate(parser, kind='control plane'):
|
|
"""Adds SSH config EC2 key pair related flags for update."""
|
|
group = parser.add_group('SSH config', mutex=True)
|
|
AddSshEC2KeyPair(group, kind)
|
|
AddClearSshEc2KeyPair(group, kind)
|
|
|
|
|
|
def AddRoleArn(parser, required=True):
|
|
parser.add_argument(
|
|
'--role-arn',
|
|
required=required,
|
|
help=(
|
|
'Amazon Resource Name (ARN) of the IAM role to assume when '
|
|
'managing AWS resources.'
|
|
),
|
|
)
|
|
|
|
|
|
def GetRoleArn(args):
|
|
return getattr(args, 'role_arn', None)
|
|
|
|
|
|
def AddRoleSessionName(parser):
|
|
parser.add_argument(
|
|
'--role-session-name', help='Identifier for the assumed role session.'
|
|
)
|
|
|
|
|
|
def GetRoleSessionName(args):
|
|
return getattr(args, 'role_session_name', None)
|
|
|
|
|
|
def AddSecurityGroupIds(parser, kind='control plane'):
|
|
"""Adds the --security-group-ids flag."""
|
|
parser.add_argument(
|
|
'--security-group-ids',
|
|
type=arg_parsers.ArgList(),
|
|
metavar='SECURITY_GROUP_ID',
|
|
help=(
|
|
"IDs of additional security groups to add to the {}'s nodes.".format(
|
|
kind
|
|
)
|
|
),
|
|
)
|
|
|
|
|
|
def GetSecurityGroupIds(args):
|
|
return getattr(args, 'security_group_ids', None) or []
|
|
|
|
|
|
def AddClearSecurityGroupIds(parser, noun):
|
|
"""Adds flag for clearing the security groups.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
noun: The resource type to which the flag is applicable.
|
|
"""
|
|
|
|
parser.add_argument(
|
|
'--clear-security-group-ids',
|
|
action='store_true',
|
|
default=None,
|
|
help=(
|
|
'Clear any additional security groups associated with the '
|
|
"{}'s nodes. This does not remove the default security groups."
|
|
.format(noun)
|
|
),
|
|
)
|
|
|
|
|
|
def AddSecurityGroupFlagsForUpdate(parser, noun):
|
|
"""Adds security group related flags for update.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
noun: The resource type to which the flags are applicable.
|
|
"""
|
|
|
|
group = parser.add_group('Security groups', mutex=True)
|
|
AddSecurityGroupIds(group, noun)
|
|
AddClearSecurityGroupIds(group, noun)
|
|
|
|
|
|
def AddPerNodePoolSGRules(parser):
|
|
"""Adds --disable-per-node-pool-sg-rules flag to parser."""
|
|
|
|
parser.add_argument(
|
|
'--disable-per-node-pool-sg-rules',
|
|
action='store_true',
|
|
default=None,
|
|
dest='per_node_pool_sg_rules_disabled',
|
|
help=(
|
|
'Disable the default per node pool subnet security group rules on '
|
|
'the control plane security group. When disabled, at least one '
|
|
'security group that allows node pools to send traffic to '
|
|
'the control plane on ports TCP/443 and TCP/8132 must be provided.'
|
|
),
|
|
)
|
|
|
|
|
|
def GetPerNodePoolSGRulesDisabled(parser):
|
|
return getattr(parser, 'per_node_pool_sg_rules_disabled', None)
|
|
|
|
|
|
def AddPerNodePoolSGRulesForUpdate(parser):
|
|
"""Adds --disable-per-node-pool-sg-rules and --enable-per-node-pool-sg-rules flags to parser."""
|
|
|
|
group = parser.add_group(
|
|
'Default per node pool security group rules', mutex=True
|
|
)
|
|
AddPerNodePoolSGRules(group)
|
|
group.add_argument(
|
|
'--enable-per-node-pool-sg-rules',
|
|
action='store_false',
|
|
default=None,
|
|
dest='per_node_pool_sg_rules_disabled',
|
|
help=(
|
|
'Enable the default per node pool subnet security group rules on '
|
|
'the control plane security group.'
|
|
),
|
|
)
|
|
|
|
|
|
def _VolumeTypeEnumMapper(prefix):
|
|
return arg_utils.ChoiceEnumMapper(
|
|
'--{}-volume-type'.format(prefix),
|
|
api_util.GetMessagesModule().GoogleCloudGkemulticloudV1AwsVolumeTemplate.VolumeTypeValueValuesEnum,
|
|
include_filter=lambda volume_type: 'UNSPECIFIED' not in volume_type,
|
|
help_str='Type of the {} volume.'.format(prefix),
|
|
)
|
|
|
|
|
|
def AddRootVolumeType(parser):
|
|
_VolumeTypeEnumMapper('root').choice_arg.AddToParser(parser)
|
|
|
|
|
|
def AddMainVolumeType(parser):
|
|
_VolumeTypeEnumMapper('main').choice_arg.AddToParser(parser)
|
|
|
|
|
|
def GetRootVolumeType(args):
|
|
if getattr(args, 'root_volume_type', None):
|
|
return _VolumeTypeEnumMapper('root').GetEnumForChoice(args.root_volume_type)
|
|
|
|
|
|
def GetMainVolumeType(args):
|
|
if getattr(args, 'main_volume_type', None):
|
|
return _VolumeTypeEnumMapper('main').GetEnumForChoice(args.main_volume_type)
|
|
|
|
|
|
def _AddVolumeIops(parser, prefix):
|
|
parser.add_argument(
|
|
'--{}-volume-iops'.format(prefix),
|
|
type=int,
|
|
help=(
|
|
'Number of I/O operations per second (IOPS) to provision '
|
|
'for the {} volume.'.format(prefix)
|
|
),
|
|
)
|
|
|
|
|
|
def AddRootVolumeIops(parser):
|
|
_AddVolumeIops(parser, 'root')
|
|
|
|
|
|
def GetRootVolumeIops(args):
|
|
return getattr(args, 'root_volume_iops', None)
|
|
|
|
|
|
def AddMainVolumeIops(parser):
|
|
_AddVolumeIops(parser, 'main')
|
|
|
|
|
|
def GetMainVolumeIops(args):
|
|
return getattr(args, 'main_volume_iops', None)
|
|
|
|
|
|
def _AddVolumeThroughput(parser, prefix):
|
|
parser.add_argument(
|
|
'--{}-volume-throughput'.format(prefix),
|
|
type=int,
|
|
help=(
|
|
'Throughput to provision for the {} volume, in MiB/s. Only valid '
|
|
'if the volume type is GP3. If volume type is GP3 and throughput '
|
|
'is not provided, it defaults to 125.'.format(prefix)
|
|
),
|
|
)
|
|
|
|
|
|
def AddRootVolumeThroughput(parser):
|
|
_AddVolumeThroughput(parser, 'root')
|
|
|
|
|
|
def GetRootVolumeThroughput(args):
|
|
return getattr(args, 'root_volume_throughput', None)
|
|
|
|
|
|
def AddMainVolumeThroughput(parser):
|
|
_AddVolumeThroughput(parser, 'main')
|
|
|
|
|
|
def GetMainVolumeThroughput(args):
|
|
return getattr(args, 'main_volume_throughput', None)
|
|
|
|
|
|
def _AddKmsKeyArn(parser, prefix, target, required=False):
|
|
parser.add_argument(
|
|
'--{}-kms-key-arn'.format(prefix),
|
|
required=required,
|
|
help=(
|
|
'Amazon Resource Name (ARN) of the AWS KMS key to encrypt the {}.'
|
|
.format(target)
|
|
),
|
|
)
|
|
|
|
|
|
def AddRootVolumeKmsKeyArn(parser):
|
|
_AddKmsKeyArn(parser, 'root-volume', 'root volume')
|
|
|
|
|
|
def GetRootVolumeKmsKeyArn(args):
|
|
return getattr(args, 'root_volume_kms_key_arn', None)
|
|
|
|
|
|
def AddMainVolumeKmsKeyArn(parser):
|
|
_AddKmsKeyArn(parser, 'main-volume', 'main volume')
|
|
|
|
|
|
def GetMainVolumeKmsKeyArn(args):
|
|
return getattr(args, 'main_volume_kms_key_arn', None)
|
|
|
|
|
|
def AddDatabaseEncryptionKmsKeyArn(parser):
|
|
_AddKmsKeyArn(parser, 'database-encryption', 'cluster secrets', required=True)
|
|
|
|
|
|
def GetDatabaseEncryptionKmsKeyArn(args):
|
|
return getattr(args, 'database_encryption_kms_key_arn', None)
|
|
|
|
|
|
def AddConfigEncryptionKmsKeyArn(parser, required=True):
|
|
_AddKmsKeyArn(parser, 'config-encryption', 'user data', required=required)
|
|
|
|
|
|
def GetConfigEncryptionKmsKeyArn(args):
|
|
return getattr(args, 'config_encryption_kms_key_arn', None)
|
|
|
|
|
|
def _TenancyEnumMapper():
|
|
return arg_utils.ChoiceEnumMapper(
|
|
'--instance-placement',
|
|
api_util.GetMessagesModule().GoogleCloudGkemulticloudV1AwsInstancePlacement.TenancyValueValuesEnum,
|
|
include_filter=lambda tenancy: 'UNSPECIFIED' not in tenancy,
|
|
help_str='Type of the tenancy.',
|
|
)
|
|
|
|
|
|
def AddInstancePlacement(parser):
|
|
return _TenancyEnumMapper().choice_arg.AddToParser(parser)
|
|
|
|
|
|
def GetInstancePlacement(args):
|
|
instance_placement = getattr(args, 'instance_placement', None)
|
|
return (
|
|
_TenancyEnumMapper().GetEnumForChoice(instance_placement)
|
|
if instance_placement
|
|
else None
|
|
)
|
|
|
|
|
|
def AddClearProxyConfig(parser, noun):
|
|
"""Adds flag for clearing the proxy configuration.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
noun: The resource type to which the flag is applicable.
|
|
"""
|
|
|
|
parser.add_argument(
|
|
'--clear-proxy-config',
|
|
action='store_true',
|
|
default=None,
|
|
help='Clear the proxy configuration associated with the {}.'.format(noun),
|
|
)
|
|
|
|
|
|
def AddProxySecretArn(parser, required=False):
|
|
parser.add_argument(
|
|
'--proxy-secret-arn',
|
|
required=required,
|
|
help=(
|
|
'ARN of the AWS Secrets Manager secret that contains a proxy '
|
|
'configuration.'
|
|
),
|
|
)
|
|
|
|
|
|
def GetProxySecretArn(args):
|
|
return getattr(args, 'proxy_secret_arn', None)
|
|
|
|
|
|
def AddProxySecretVersionId(parser, required=False):
|
|
parser.add_argument(
|
|
'--proxy-secret-version-id',
|
|
required=required,
|
|
help=(
|
|
'Version ID string of the AWS Secrets Manager secret that contains '
|
|
'a proxy configuration.'
|
|
),
|
|
)
|
|
|
|
|
|
def GetProxySecretVersionId(args):
|
|
return getattr(args, 'proxy_secret_version_id', None)
|
|
|
|
|
|
def AddProxyConfig(parser):
|
|
"""Adds proxy configuration flags.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
"""
|
|
|
|
group = parser.add_argument_group('Proxy config')
|
|
AddProxySecretArn(group, required=True)
|
|
AddProxySecretVersionId(group, required=True)
|
|
|
|
|
|
def AddProxyConfigForUpdate(parser, noun):
|
|
"""Adds proxy configuration flags for update.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
noun: The resource type to which the flags are applicable.
|
|
"""
|
|
|
|
group = parser.add_group('Proxy config', mutex=True)
|
|
update_proxy_group = group.add_group(
|
|
'Update existing proxy config parameters'
|
|
)
|
|
AddProxySecretArn(update_proxy_group)
|
|
AddProxySecretVersionId(update_proxy_group)
|
|
AddClearProxyConfig(group, noun)
|
|
|
|
|
|
def GetSubnetIds(args):
|
|
return getattr(args, 'subnet_ids', None) or []
|
|
|
|
|
|
def AddAutoScalingMetricsCollection(parser):
|
|
"""Adds autoscaling metrics collection flags.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
"""
|
|
|
|
group = parser.add_argument_group('Node pool autoscaling metrics collection')
|
|
AddAutoscalingMetricsGranularity(group, required=True)
|
|
AddAutoscalingMetrics(group)
|
|
|
|
|
|
def AddAutoscalingMetricsGranularity(parser, required=False):
|
|
parser.add_argument(
|
|
'--autoscaling-metrics-granularity',
|
|
required=required,
|
|
help=(
|
|
'Frequency at which EC2 Auto Scaling sends aggregated data to '
|
|
'AWS CloudWatch. The only valid value is "1Minute".'
|
|
),
|
|
)
|
|
|
|
|
|
def GetAutoscalingMetricsGranularity(args):
|
|
return getattr(args, 'autoscaling_metrics_granularity', None)
|
|
|
|
|
|
def AddAutoscalingMetrics(parser):
|
|
parser.add_argument(
|
|
'--autoscaling-metrics',
|
|
type=arg_parsers.ArgList(),
|
|
metavar='AUTOSCALING_METRIC',
|
|
required=False,
|
|
help=(
|
|
'Autoscaling metrics to enable. For a list of valid metrics, '
|
|
'refer to https://docs.aws.amazon.com/autoscaling/ec2/APIReference/'
|
|
'API_EnableMetricsCollection.html. If granularity is specified '
|
|
'but not any metrics, all metrics are enabled.'
|
|
),
|
|
)
|
|
|
|
|
|
def GetAutoscalingMetrics(args):
|
|
return getattr(args, 'autoscaling_metrics', None)
|
|
|
|
|
|
def AddAutoScalingMetricsCollectionForUpdate(parser):
|
|
"""Adds autoscaling metrics collection flags for update.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
"""
|
|
|
|
group = parser.add_group(
|
|
'Node pool autoscaling metrics collection', mutex=True
|
|
)
|
|
update_metrics_group = group.add_group(
|
|
'Update existing cloudwatch autoscaling metrics collection parameters'
|
|
)
|
|
AddAutoscalingMetricsGranularity(update_metrics_group)
|
|
AddAutoscalingMetrics(update_metrics_group)
|
|
AddClearAutoscalingMetrics(group)
|
|
|
|
|
|
def AddClearAutoscalingMetrics(parser):
|
|
"""Adds flag for clearing the cloudwatch autoscaling metrics collection.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
"""
|
|
|
|
parser.add_argument(
|
|
'--clear-autoscaling-metrics',
|
|
action='store_true',
|
|
default=None,
|
|
help=(
|
|
'Clear the cloudwatch autoscaling metrics collection '
|
|
'associated with the nodepool.'
|
|
),
|
|
)
|
|
|
|
|
|
def AddKubeletConfigCpuManagerPolicy(parser):
|
|
"""Sets kubelet configuration CPU manager policy.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
"""
|
|
parser.add_argument(
|
|
'--kubelet-config-cpu-manager-policy',
|
|
required=False,
|
|
help=(
|
|
'Kubelet CPU manager policy.'
|
|
),
|
|
choices=['none', 'static']
|
|
)
|
|
|
|
|
|
def GetKubeletConfigCpuManagerPolicy(args):
|
|
return getattr(args, 'kubelet_config_cpu_manager_policy', None)
|
|
|
|
|
|
def AddKubeletConfigCpuCfsQuota(parser):
|
|
"""Sets kubelet configuration CPU CFS quota.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
"""
|
|
parser.add_argument(
|
|
'--kubelet-config-cpu-cfs-quota',
|
|
type=bool,
|
|
required=False,
|
|
help=(
|
|
'Enforce a Kubelet CPU CFS quota.'
|
|
),
|
|
)
|
|
|
|
|
|
def GetKubeletConfigCpuCfsQuota(args):
|
|
return getattr(args, 'kubelet_config_cpu_cfs_quota', None)
|
|
|
|
|
|
def AddKubeletConfigCpuCfsQuotaPeriod(parser):
|
|
"""Sets kubelet configuration CPU CFS quota period.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
"""
|
|
parser.add_argument(
|
|
'--kubelet-config-cpu-cfs-quota-period',
|
|
required=False,
|
|
help=(
|
|
'Kubelet CPU CFS quota period, within the range "1ms" to "1s".'
|
|
),
|
|
)
|
|
|
|
|
|
def GetKubeletConfigCpuCfsQuotaPeriod(args):
|
|
return getattr(args, 'kubelet_config_cpu_cfs_quota_period', None)
|
|
|
|
|
|
def AddKubeletConfigPodPidsLimit(parser):
|
|
"""Sets kubelet configuration pod PIDS limit.
|
|
|
|
Args:
|
|
parser: The argparse.parser to add the arguments to.
|
|
"""
|
|
parser.add_argument(
|
|
'--kubelet-config-pod-pids-limit',
|
|
type=int,
|
|
required=False,
|
|
help=(
|
|
'Kubelet maximum number of PIDS in any pod, within the '
|
|
'range 1024 to 4194304.'
|
|
),
|
|
)
|
|
|
|
|
|
def GetKubeletConfigPodPidsLimit(args):
|
|
return getattr(args, 'kubelet_config_pod_pids_limit', None)
|