1
# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
3
# Permission is hereby granted, free of charge, to any person obtaining a
4
# copy of this software and associated documentation files (the
5
# "Software"), to deal in the Software without restriction, including
6
# without limitation the rights to use, copy, modify, merge, publish, dis-
7
# tribute, sublicense, and/or sell copies of the Software, and to permit
8
# persons to whom the Software is furnished to do so, subject to the fol-
11
# The above copyright notice and this permission notice shall be included
12
# in all copies or substantial portions of the Software.
14
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23
Represents an EC2 Security Group
25
from boto.ec2.ec2object import EC2Object
26
from boto.exception import BotoClientError
28
class SecurityGroup(EC2Object):
30
def __init__(self, connection=None, owner_id=None,
31
name=None, description=None):
32
EC2Object.__init__(self, connection)
33
self.owner_id = owner_id
35
self.description = description
39
return 'SecurityGroup:%s' % self.name
41
def startElement(self, name, attrs, connection):
43
self.rules.append(IPPermissions(self))
48
def endElement(self, name, value, connection):
51
elif name == 'groupName':
53
elif name == 'groupDescription':
54
self.description = value
55
elif name == 'ipRanges':
57
elif name == 'return':
64
'Unexpected value of status %s for group %s'%(
70
setattr(self, name, value)
73
return self.connection.delete_security_group(self.name)
75
def add_rule(self, ip_protocol, from_port, to_port,
76
src_group_name, src_group_owner_id, cidr_ip):
77
rule = IPPermissions(self)
78
rule.ip_protocol = ip_protocol
79
rule.from_port = from_port
80
rule.to_port = to_port
81
self.rules.append(rule)
82
rule.add_grant(src_group_name, src_group_owner_id, cidr_ip)
84
def remove_rule(self, ip_protocol, from_port, to_port,
85
src_group_name, src_group_owner_id, cidr_ip):
87
for rule in self.rules:
88
if rule.ip_protocol == ip_protocol:
89
if rule.from_port == from_port:
90
if rule.to_port == to_port:
93
for grant in rule.grants:
94
if grant.name == src_group_name:
95
if grant.owner_id == src_group_owner_id:
96
if grant.cidr_ip == cidr_ip:
99
rule.grants.remove(target_grant)
100
if len(rule.grants) == 0:
101
self.rules.remove(target_rule)
103
def authorize(self, ip_protocol=None, from_port=None, to_port=None,
104
cidr_ip=None, src_group=None):
106
Add a new rule to this security group.
107
You need to pass in either src_group_name
108
OR ip_protocol, from_port, to_port,
109
and cidr_ip. In other words, either you are authorizing another
110
group or you are authorizing some ip-based rule.
112
:type ip_protocol: string
113
:param ip_protocol: Either tcp | udp | icmp
116
:param from_port: The beginning port number you are enabling
119
:param to_port: The ending port number you are enabling
121
:type to_port: string
122
:param to_port: The CIDR block you are providing access to.
123
See http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
125
:type src_group: :class:`boto.ec2.securitygroup.SecurityGroup` or
126
:class:`boto.ec2.securitygroup.GroupOrCIDR`
129
:return: True if successful.
136
src_group_name = src_group.name
137
src_group_owner_id = src_group.owner_id
139
src_group_name = None
140
src_group_owner_id = None
141
status = self.connection.authorize_security_group(self.name,
149
self.add_rule(ip_protocol, from_port, to_port, src_group_name,
150
src_group_owner_id, cidr_ip)
153
def revoke(self, ip_protocol=None, from_port=None, to_port=None,
154
cidr_ip=None, src_group=None):
160
src_group_name = src_group.name
161
src_group_owner_id = src_group.owner_id
163
src_group_name = None
164
src_group_owner_id = None
165
status = self.connection.revoke_security_group(self.name,
173
self.remove_rule(ip_protocol, from_port, to_port, src_group_name,
174
src_group_owner_id, cidr_ip)
177
def copy_to_region(self, region, name=None):
179
Create a copy of this security group in another region.
180
Note that the new security group will be a separate entity
181
and will not stay in sync automatically after the copy
184
:type region: :class:`boto.ec2.regioninfo.RegionInfo`
185
:param region: The region to which this security group will be copied.
188
:param name: The name of the copy. If not supplied, the copy
189
will have the same name as this security group.
191
:rtype: :class:`boto.ec2.securitygroup.SecurityGroup`
192
:return: The new security group.
194
if region.name == self.region:
195
raise BotoClientError('Unable to copy to the same Region')
196
conn_params = self.connection.get_params()
197
rconn = region.connect(**conn_params)
198
sg = rconn.create_security_group(name or self.name, self.description)
200
for rule in self.rules:
201
grant = rule.grants[0]
203
if grant.name not in source_groups:
204
source_groups.append(grant.name)
205
sg.authorize(None, None, None, None, grant)
207
sg.authorize(rule.ip_protocol, rule.from_port, rule.to_port,
213
rs = self.connection.get_all_instances()
214
for reservation in rs:
215
uses_group = [g.id for g in reservation.groups if g.id == self.name]
217
instances.extend(reservation.instances)
222
def __init__(self, parent=None):
224
self.ip_protocol = None
225
self.from_port = None
230
return 'IPPermissions:%s(%s-%s)' % (self.ip_protocol,
231
self.from_port, self.to_port)
233
def startElement(self, name, attrs, connection):
235
self.grants.append(GroupOrCIDR(self))
236
return self.grants[-1]
239
def endElement(self, name, value, connection):
240
if name == 'ipProtocol':
241
self.ip_protocol = value
242
elif name == 'fromPort':
243
self.from_port = value
244
elif name == 'toPort':
247
setattr(self, name, value)
249
def add_grant(self, name=None, owner_id=None, cidr_ip=None):
250
grant = GroupOrCIDR(self)
251
grant.owner_id = owner_id
253
grant.cidr_ip = cidr_ip
254
self.grants.append(grant)
259
def __init__(self, parent=None):
266
return '%s' % self.cidr_ip
268
return '%s-%s' % (self.name, self.owner_id)
270
def startElement(self, name, attrs, connection):
273
def endElement(self, name, value, connection):
275
self.owner_id = value
276
elif name == 'groupName':
281
setattr(self, name, value)