1# -*- coding: utf-8 -*- # 2# Copyright 2017 Google LLC. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15"""Flags and helpers for the compute interconnects commands.""" 16 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import unicode_literals 20 21import collections 22 23from googlecloudsdk.calliope import arg_parsers 24from googlecloudsdk.calliope import base 25from googlecloudsdk.command_lib.compute import completers as compute_completers 26from googlecloudsdk.command_lib.compute import flags as compute_flags 27 28_BANDWIDTH_CHOICES = collections.OrderedDict([ 29 ('50m', '50 Mbit/s'), 30 ('100m', '100 Mbit/s'), 31 ('200m', '200 Mbit/s'), 32 ('300m', '300 Mbit/s'), 33 ('400m', '400 Mbit/s'), 34 ('500m', '500 Mbit/s'), 35 ('1g', '1 Gbit/s'), 36 ('2g', '2 Gbit/s'), 37 ('5g', '5 Gbit/s'), 38 ('10g', '10 Gbit/s'), 39 ('20g', '20 Gbit/s'), 40 ('50g', '50 Gbit/s'), 41]) 42 43_EDGE_AVAILABILITY_DOMAIN_CHOICES = { 44 'availability-domain-1': 'Edge Availability Domain 1', 45 'availability-domain-2': 'Edge Availability Domain 2', 46 'any': 'Any Availability Domain', 47} 48 49 50class InterconnectAttachmentsCompleter(compute_completers.ListCommandCompleter): 51 52 def __init__(self, **kwargs): 53 super(InterconnectAttachmentsCompleter, self).__init__( 54 collection='compute.interconnectAttachments', 55 list_command='alpha compute interconnects attachments list --uri', 56 **kwargs) 57 58 59def InterconnectAttachmentArgument(required=True, plural=False): 60 return compute_flags.ResourceArgument( 61 resource_name='interconnect attachment', 62 completer=InterconnectAttachmentsCompleter, 63 plural=plural, 64 required=required, 65 regional_collection='compute.interconnectAttachments', 66 region_explanation=compute_flags.REGION_PROPERTY_EXPLANATION) 67 68 69def InterconnectAttachmentArgumentForRouter(required=False, 70 plural=False, 71 operation_type='added'): 72 resource_name = 'interconnectAttachment{0}'.format('s' if plural else '') 73 return compute_flags.ResourceArgument( 74 resource_name=resource_name, 75 name='--interconnect-attachment', 76 completer=InterconnectAttachmentsCompleter, 77 plural=plural, 78 required=required, 79 regional_collection='compute.interconnectAttachments', 80 short_help='The interconnect attachment of the interface being {0}.' 81 .format(operation_type), 82 region_explanation='If not specified it will be set to the region of ' 83 'the router.') 84 85 86def AddAdminEnabled(parser, default_behavior=True, update=False): 87 """Adds adminEnabled flag to the argparse.ArgumentParser.""" 88 group = parser.add_group(mutex=True, required=False, help='') 89 if update: 90 # Update command 91 help_text = """\ 92 Administrative status of the interconnect attachment. 93 When this is enabled, the attachment is operational and will carry 94 traffic. Use --no-enable-admin to disable it. 95 """ 96 elif default_behavior: 97 # Create command for dedicated attachments, backend default behavior is to 98 # enable if not specified. 99 help_text = """\ 100 Administrative status of the interconnect attachment. If not provided 101 on creation, defaults to enabled. 102 When this is enabled, the attachment is operational and will carry 103 traffic. Use --no-enable-admin to disable it. 104 """ 105 else: 106 # Create command for partner attachments, backend default behavior is to 107 # disabled if not specified. 108 help_text = """\ 109 Administrative status of the interconnect attachment. If not provided 110 on creation, defaults to disabled. 111 When this is enabled, the attachment is operational and will carry 112 traffic. Use --no-enable-admin to disable it. 113 """ 114 115 group.add_argument( 116 '--admin-enabled', 117 hidden=True, 118 default=None, 119 action='store_true', 120 help='(DEPRECATED) Use --enable-admin instead.') 121 122 group.add_argument( 123 '--enable-admin', action='store_true', default=None, help=help_text) 124 125 126def AddBandwidth(parser, required): 127 """Adds bandwidth flag to the argparse.ArgumentParser.""" 128 help_text = """\ 129 Provisioned capacity of the attachment. 130 """ 131 choices = _BANDWIDTH_CHOICES 132 133 base.ChoiceArgument( 134 '--bandwidth', 135 # TODO(b/80311900): use arg_parsers.BinarySize() 136 choices=choices, 137 required=required, 138 help_str=help_text).AddToParser(parser) 139 140 141def AddVlan(parser): 142 """Adds vlan flag to the argparse.ArgumentParser.""" 143 parser.add_argument( 144 '--vlan', 145 type=int, 146 help="""\ 147 Desired VLAN for this attachment, in the range 2-4094. If not supplied, 148 Google will automatically select a VLAN. 149 """) 150 151 152def AddPartnerAsn(parser): 153 """Adds partner asn flag to the argparse.ArgumentParser.""" 154 parser.add_argument( 155 '--partner-asn', 156 type=int, 157 help="""\ 158 BGP ASN of the partner. This should only be supplied by layer 3 159 providers that have configured BGP on behalf of the customer. 160 """) 161 162 163def AddPartnerMetadata(parser, required=True): 164 """Adds partner metadata flags to the argparse.ArgumentParser.""" 165 group = parser.add_group( 166 mutex=False, required=required, help='Partner metadata.') 167 group.add_argument( 168 '--partner-name', 169 required=required, 170 help="""\ 171 Plain text name of the Partner providing this attachment. This value 172 may be validated to match approved Partner values. 173 """) 174 group.add_argument( 175 '--partner-interconnect-name', 176 required=required, 177 help="""\ 178 Plain text name of the Interconnect this attachment is connected to, 179 as displayed in the Partner's portal. For instance "Chicago 1". 180 """) 181 group.add_argument( 182 '--partner-portal-url', 183 required=required, 184 help="""\ 185 URL of the Partner's portal for this Attachment. The Partner may wish 186 to customize this to be a deep-link to the specific resource on the 187 Partner portal. This value may be validated to match approved Partner 188 values. 189 """) 190 191 192def AddPairingKey(parser): 193 """Adds pairing key flag to the argparse.ArgumentParser.""" 194 parser.add_argument( 195 '--pairing-key', 196 required=True, 197 help="""\ 198 Value of the pairing-key from the target partner attachment provided by 199 the customer. 200 """) 201 202 203def AddEdgeAvailabilityDomain(parser): 204 """Adds edge-availability-domain flag to the argparse.ArgumentParser.""" 205 parser.add_argument( 206 '--edge-availability-domain', 207 choices=_EDGE_AVAILABILITY_DOMAIN_CHOICES, 208 required=True, 209 metavar='AVAILABILITY_DOMAIN', 210 help="""\ 211 Desired edge availability domain for this attachment: 212 `availability-domain-1`, `availability-domain-2`, `any`. 213 214 In each metro where the Partner can connect to Google, there are two sets 215 of redundant hardware. These sets are described as edge availability 216 domain 1 and 2. Within a metro, Google will only schedule maintenance in 217 one availability domain at a time. This guarantee does not apply to 218 availability domains outside the metro; Google may perform maintenance in 219 (say) New York availability domain 1 at the same time as Chicago 220 availability domain 1. 221 """) 222 223 224def AddDescription(parser): 225 """Adds description flag to the argparse.ArgumentParser.""" 226 parser.add_argument( 227 '--description', 228 help='Human-readable plain-text description of attachment.') 229 230 231def AddCandidateSubnets(parser): 232 """Adds candidate subnets flag to the argparse.ArgumetnParser.""" 233 parser.add_argument( 234 '--candidate-subnets', 235 type=arg_parsers.ArgList(max_length=16), 236 metavar='SUBNET', 237 help="""\ 238 Up to 16 candidate prefixes that can be used to restrict the allocation of 239 `cloudRouterIpAddress` and `customerRouterIpAddress` for this 240 attachment. All prefixes must be within link-local address space. Google 241 will attempt to select an unused /29 from the supplied candidate 242 subnet(s), or all of link-local space if no subnets supplied. Google will 243 not re-use a /29 already in-use by your project, even if it's contained in 244 one of the candidate subnets. The request will fail if all /29s within the 245 candidate subnets are in use at Google's edge.""", 246 default=[]) 247 248 249def AddDryRun(parser): 250 """Adds dry-run flag to the argparse.ArgumentParser.""" 251 parser.add_argument( 252 '--dry-run', 253 default=None, 254 action='store_true', 255 help='If supplied, validates the attachment without creating it.') 256 257 258def AddMtu(parser): 259 """Adds mtu flag to the argparse.ArgumentParser.""" 260 parser.add_argument( 261 '--mtu', 262 type=int, 263 help="""\ 264 Maximum transmission unit (MTU) is the size of the largest IP packet 265 passing through this interconnect attachment. Only 1440 and 1500 are 266 allowed values. If not specified, the value will default to 1440. 267 """) 268 269 270def GetAdminEnabledFlag(args): 271 """Determines value of admin_enabled/enable_admin flag.""" 272 return args.enable_admin if args.enable_admin is not None else args.admin_enabled 273