Path: blob/develop/awscli/customizations/ec2/runinstances.py
1567 views
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.1#2# Licensed under the Apache License, Version 2.0 (the "License"). You3# may not use this file except in compliance with the License. A copy of4# the License is located at5#6# http://aws.amazon.com/apache2.0/7#8# or in the "license" file accompanying this file. This file is9# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF10# ANY KIND, either express or implied. See the License for the specific11# language governing permissions and limitations under the License.12"""13This customization adds two new parameters to the ``ec2 run-instance``14command. The first, ``--secondary-private-ip-addresses`` allows a list15of IP addresses within the specified subnet to be associated with the16new instance. The second, ``--secondary-ip-address-count`` allows you17to specify how many additional IP addresses you want but the actual18address will be assigned for you.1920This functionality (and much more) is also available using the21``--network-interfaces`` complex argument. This just makes two of22the most commonly used features available more easily.23"""24from awscli.arguments import CustomArgument2526# --secondary-private-ip-address27SECONDARY_PRIVATE_IP_ADDRESSES_DOCS = (28'[EC2-VPC] A secondary private IP address for the network interface '29'or instance. You can specify this multiple times to assign multiple '30'secondary IP addresses. If you want additional private IP addresses '31'but do not need a specific address, use the '32'--secondary-private-ip-address-count option.')3334# --secondary-private-ip-address-count35SECONDARY_PRIVATE_IP_ADDRESS_COUNT_DOCS = (36'[EC2-VPC] The number of secondary IP addresses to assign to '37'the network interface or instance.')3839# --associate-public-ip-address40ASSOCIATE_PUBLIC_IP_ADDRESS_DOCS = (41'[EC2-VPC] If specified a public IP address will be assigned '42'to the new instance in a VPC.')434445def _add_params(argument_table, **kwargs):46arg = SecondaryPrivateIpAddressesArgument(47name='secondary-private-ip-addresses',48help_text=SECONDARY_PRIVATE_IP_ADDRESSES_DOCS)49argument_table['secondary-private-ip-addresses'] = arg50arg = SecondaryPrivateIpAddressCountArgument(51name='secondary-private-ip-address-count',52help_text=SECONDARY_PRIVATE_IP_ADDRESS_COUNT_DOCS)53argument_table['secondary-private-ip-address-count'] = arg54arg = AssociatePublicIpAddressArgument(55name='associate-public-ip-address',56help_text=ASSOCIATE_PUBLIC_IP_ADDRESS_DOCS,57action='store_true', group_name='associate_public_ip')58argument_table['associate-public-ip-address'] = arg59arg = NoAssociatePublicIpAddressArgument(60name='no-associate-public-ip-address',61help_text=ASSOCIATE_PUBLIC_IP_ADDRESS_DOCS,62action='store_false', group_name='associate_public_ip')63argument_table['no-associate-public-ip-address'] = arg646566def _check_args(parsed_args, **kwargs):67# This function checks the parsed args. If the user specified68# the --network-interfaces option with any of the scalar options we69# raise an error.70arg_dict = vars(parsed_args)71if arg_dict['network_interfaces']:72for key in ('secondary_private_ip_addresses',73'secondary_private_ip_address_count',74'associate_public_ip_address'):75if arg_dict[key]:76msg = ('Mixing the --network-interfaces option '77'with the simple, scalar options is '78'not supported.')79raise ValueError(msg)808182def _fix_args(params, **kwargs):83# The RunInstances request provides some parameters84# such as --subnet-id and --security-group-id that can be specified85# as separate options only if the request DOES NOT include a86# NetworkInterfaces structure. In those cases, the values for87# these parameters must be specified inside the NetworkInterfaces88# structure. This function checks for those parameters89# and fixes them if necessary.90# NOTE: If the user is a default VPC customer, RunInstances91# allows them to specify the security group by name or by id.92# However, in this scenario we can only support id because93# we can't place a group name in the NetworkInterfaces structure.94network_interface_params = [95'PrivateIpAddresses',96'SecondaryPrivateIpAddressCount',97'AssociatePublicIpAddress'98]99if 'NetworkInterfaces' in params:100interface = params['NetworkInterfaces'][0]101if any(param in interface for param in network_interface_params):102if 'SubnetId' in params:103interface['SubnetId'] = params['SubnetId']104del params['SubnetId']105if 'SecurityGroupIds' in params:106interface['Groups'] = params['SecurityGroupIds']107del params['SecurityGroupIds']108if 'PrivateIpAddress' in params:109ip_addr = {'PrivateIpAddress': params['PrivateIpAddress'],110'Primary': True}111interface['PrivateIpAddresses'] = [ip_addr]112del params['PrivateIpAddress']113if 'Ipv6AddressCount' in params:114interface['Ipv6AddressCount'] = params['Ipv6AddressCount']115del params['Ipv6AddressCount']116if 'Ipv6Addresses' in params:117interface['Ipv6Addresses'] = params['Ipv6Addresses']118del params['Ipv6Addresses']119if 'EnablePrimaryIpv6' in params:120interface['PrimaryIpv6'] = params['EnablePrimaryIpv6']121del params['EnablePrimaryIpv6']122123124EVENTS = [125('building-argument-table.ec2.run-instances', _add_params),126('operation-args-parsed.ec2.run-instances', _check_args),127('before-parameter-build.ec2.RunInstances', _fix_args),128]129130131def register_runinstances(event_handler):132# Register all of the events for customizing BundleInstance133for event, handler in EVENTS:134event_handler.register(event, handler)135136137def _build_network_interfaces(params, key, value):138# Build up the NetworkInterfaces data structure139if 'NetworkInterfaces' not in params:140params['NetworkInterfaces'] = [{'DeviceIndex': 0}]141142if key == 'PrivateIpAddresses':143if 'PrivateIpAddresses' not in params['NetworkInterfaces'][0]:144params['NetworkInterfaces'][0]['PrivateIpAddresses'] = value145else:146params['NetworkInterfaces'][0][key] = value147148149class SecondaryPrivateIpAddressesArgument(CustomArgument):150151def add_to_parser(self, parser, cli_name=None):152parser.add_argument(self.cli_name, dest=self.py_name,153default=self._default, nargs='*')154155def add_to_params(self, parameters, value):156if value:157value = [{'PrivateIpAddress': v, 'Primary': False} for v in value]158_build_network_interfaces(159parameters, 'PrivateIpAddresses', value)160161162class SecondaryPrivateIpAddressCountArgument(CustomArgument):163164def add_to_parser(self, parser, cli_name=None):165parser.add_argument(self.cli_name, dest=self.py_name,166default=self._default, type=int)167168def add_to_params(self, parameters, value):169if value:170_build_network_interfaces(171parameters, 'SecondaryPrivateIpAddressCount', value)172173174class AssociatePublicIpAddressArgument(CustomArgument):175176def add_to_params(self, parameters, value):177if value is True:178_build_network_interfaces(179parameters, 'AssociatePublicIpAddress', value)180181182class NoAssociatePublicIpAddressArgument(CustomArgument):183184def add_to_params(self, parameters, value):185if value is False:186_build_network_interfaces(187parameters, 'AssociatePublicIpAddress', value)188189190