Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aws
GitHub Repository: aws/aws-cli
Path: blob/develop/awscli/customizations/ec2/runinstances.py
1567 views
1
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License"). You
4
# may not use this file except in compliance with the License. A copy of
5
# the License is located at
6
#
7
# http://aws.amazon.com/apache2.0/
8
#
9
# or in the "license" file accompanying this file. This file is
10
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
# ANY KIND, either express or implied. See the License for the specific
12
# language governing permissions and limitations under the License.
13
"""
14
This customization adds two new parameters to the ``ec2 run-instance``
15
command. The first, ``--secondary-private-ip-addresses`` allows a list
16
of IP addresses within the specified subnet to be associated with the
17
new instance. The second, ``--secondary-ip-address-count`` allows you
18
to specify how many additional IP addresses you want but the actual
19
address will be assigned for you.
20
21
This functionality (and much more) is also available using the
22
``--network-interfaces`` complex argument. This just makes two of
23
the most commonly used features available more easily.
24
"""
25
from awscli.arguments import CustomArgument
26
27
# --secondary-private-ip-address
28
SECONDARY_PRIVATE_IP_ADDRESSES_DOCS = (
29
'[EC2-VPC] A secondary private IP address for the network interface '
30
'or instance. You can specify this multiple times to assign multiple '
31
'secondary IP addresses. If you want additional private IP addresses '
32
'but do not need a specific address, use the '
33
'--secondary-private-ip-address-count option.')
34
35
# --secondary-private-ip-address-count
36
SECONDARY_PRIVATE_IP_ADDRESS_COUNT_DOCS = (
37
'[EC2-VPC] The number of secondary IP addresses to assign to '
38
'the network interface or instance.')
39
40
# --associate-public-ip-address
41
ASSOCIATE_PUBLIC_IP_ADDRESS_DOCS = (
42
'[EC2-VPC] If specified a public IP address will be assigned '
43
'to the new instance in a VPC.')
44
45
46
def _add_params(argument_table, **kwargs):
47
arg = SecondaryPrivateIpAddressesArgument(
48
name='secondary-private-ip-addresses',
49
help_text=SECONDARY_PRIVATE_IP_ADDRESSES_DOCS)
50
argument_table['secondary-private-ip-addresses'] = arg
51
arg = SecondaryPrivateIpAddressCountArgument(
52
name='secondary-private-ip-address-count',
53
help_text=SECONDARY_PRIVATE_IP_ADDRESS_COUNT_DOCS)
54
argument_table['secondary-private-ip-address-count'] = arg
55
arg = AssociatePublicIpAddressArgument(
56
name='associate-public-ip-address',
57
help_text=ASSOCIATE_PUBLIC_IP_ADDRESS_DOCS,
58
action='store_true', group_name='associate_public_ip')
59
argument_table['associate-public-ip-address'] = arg
60
arg = NoAssociatePublicIpAddressArgument(
61
name='no-associate-public-ip-address',
62
help_text=ASSOCIATE_PUBLIC_IP_ADDRESS_DOCS,
63
action='store_false', group_name='associate_public_ip')
64
argument_table['no-associate-public-ip-address'] = arg
65
66
67
def _check_args(parsed_args, **kwargs):
68
# This function checks the parsed args. If the user specified
69
# the --network-interfaces option with any of the scalar options we
70
# raise an error.
71
arg_dict = vars(parsed_args)
72
if arg_dict['network_interfaces']:
73
for key in ('secondary_private_ip_addresses',
74
'secondary_private_ip_address_count',
75
'associate_public_ip_address'):
76
if arg_dict[key]:
77
msg = ('Mixing the --network-interfaces option '
78
'with the simple, scalar options is '
79
'not supported.')
80
raise ValueError(msg)
81
82
83
def _fix_args(params, **kwargs):
84
# The RunInstances request provides some parameters
85
# such as --subnet-id and --security-group-id that can be specified
86
# as separate options only if the request DOES NOT include a
87
# NetworkInterfaces structure. In those cases, the values for
88
# these parameters must be specified inside the NetworkInterfaces
89
# structure. This function checks for those parameters
90
# and fixes them if necessary.
91
# NOTE: If the user is a default VPC customer, RunInstances
92
# allows them to specify the security group by name or by id.
93
# However, in this scenario we can only support id because
94
# we can't place a group name in the NetworkInterfaces structure.
95
network_interface_params = [
96
'PrivateIpAddresses',
97
'SecondaryPrivateIpAddressCount',
98
'AssociatePublicIpAddress'
99
]
100
if 'NetworkInterfaces' in params:
101
interface = params['NetworkInterfaces'][0]
102
if any(param in interface for param in network_interface_params):
103
if 'SubnetId' in params:
104
interface['SubnetId'] = params['SubnetId']
105
del params['SubnetId']
106
if 'SecurityGroupIds' in params:
107
interface['Groups'] = params['SecurityGroupIds']
108
del params['SecurityGroupIds']
109
if 'PrivateIpAddress' in params:
110
ip_addr = {'PrivateIpAddress': params['PrivateIpAddress'],
111
'Primary': True}
112
interface['PrivateIpAddresses'] = [ip_addr]
113
del params['PrivateIpAddress']
114
if 'Ipv6AddressCount' in params:
115
interface['Ipv6AddressCount'] = params['Ipv6AddressCount']
116
del params['Ipv6AddressCount']
117
if 'Ipv6Addresses' in params:
118
interface['Ipv6Addresses'] = params['Ipv6Addresses']
119
del params['Ipv6Addresses']
120
if 'EnablePrimaryIpv6' in params:
121
interface['PrimaryIpv6'] = params['EnablePrimaryIpv6']
122
del params['EnablePrimaryIpv6']
123
124
125
EVENTS = [
126
('building-argument-table.ec2.run-instances', _add_params),
127
('operation-args-parsed.ec2.run-instances', _check_args),
128
('before-parameter-build.ec2.RunInstances', _fix_args),
129
]
130
131
132
def register_runinstances(event_handler):
133
# Register all of the events for customizing BundleInstance
134
for event, handler in EVENTS:
135
event_handler.register(event, handler)
136
137
138
def _build_network_interfaces(params, key, value):
139
# Build up the NetworkInterfaces data structure
140
if 'NetworkInterfaces' not in params:
141
params['NetworkInterfaces'] = [{'DeviceIndex': 0}]
142
143
if key == 'PrivateIpAddresses':
144
if 'PrivateIpAddresses' not in params['NetworkInterfaces'][0]:
145
params['NetworkInterfaces'][0]['PrivateIpAddresses'] = value
146
else:
147
params['NetworkInterfaces'][0][key] = value
148
149
150
class SecondaryPrivateIpAddressesArgument(CustomArgument):
151
152
def add_to_parser(self, parser, cli_name=None):
153
parser.add_argument(self.cli_name, dest=self.py_name,
154
default=self._default, nargs='*')
155
156
def add_to_params(self, parameters, value):
157
if value:
158
value = [{'PrivateIpAddress': v, 'Primary': False} for v in value]
159
_build_network_interfaces(
160
parameters, 'PrivateIpAddresses', value)
161
162
163
class SecondaryPrivateIpAddressCountArgument(CustomArgument):
164
165
def add_to_parser(self, parser, cli_name=None):
166
parser.add_argument(self.cli_name, dest=self.py_name,
167
default=self._default, type=int)
168
169
def add_to_params(self, parameters, value):
170
if value:
171
_build_network_interfaces(
172
parameters, 'SecondaryPrivateIpAddressCount', value)
173
174
175
class AssociatePublicIpAddressArgument(CustomArgument):
176
177
def add_to_params(self, parameters, value):
178
if value is True:
179
_build_network_interfaces(
180
parameters, 'AssociatePublicIpAddress', value)
181
182
183
class NoAssociatePublicIpAddressArgument(CustomArgument):
184
185
def add_to_params(self, parameters, value):
186
if value is False:
187
_build_network_interfaces(
188
parameters, 'AssociatePublicIpAddress', value)
189
190