~cbehrens/nova/lp844160-build-works-with-zones

« back to all changes in this revision

Viewing changes to vendor/boto/boto/ec2/securitygroup.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
 
2
#
 
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-
 
9
# lowing conditions:
 
10
#
 
11
# The above copyright notice and this permission notice shall be included
 
12
# in all copies or substantial portions of the Software.
 
13
#
 
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
 
20
# IN THE SOFTWARE.
 
21
 
 
22
"""
 
23
Represents an EC2 Security Group
 
24
"""
 
25
from boto.ec2.ec2object import EC2Object
 
26
from boto.exception import BotoClientError
 
27
 
 
28
class SecurityGroup(EC2Object):
 
29
    
 
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
 
34
        self.name = name
 
35
        self.description = description
 
36
        self.rules = []
 
37
 
 
38
    def __repr__(self):
 
39
        return 'SecurityGroup:%s' % self.name
 
40
 
 
41
    def startElement(self, name, attrs, connection):
 
42
        if name == 'item':
 
43
            self.rules.append(IPPermissions(self))
 
44
            return self.rules[-1]
 
45
        else:
 
46
            return None
 
47
 
 
48
    def endElement(self, name, value, connection):
 
49
        if name == 'ownerId':
 
50
            self.owner_id = value
 
51
        elif name == 'groupName':
 
52
            self.name = value
 
53
        elif name == 'groupDescription':
 
54
            self.description = value
 
55
        elif name == 'ipRanges':
 
56
            pass
 
57
        elif name == 'return':
 
58
            if value == 'false':
 
59
                self.status = False
 
60
            elif value == 'true':
 
61
                self.status = True
 
62
            else:
 
63
                raise Exception(
 
64
                    'Unexpected value of status %s for group %s'%(
 
65
                        value, 
 
66
                        self.name
 
67
                    )
 
68
                )
 
69
        else:
 
70
            setattr(self, name, value)
 
71
 
 
72
    def delete(self):
 
73
        return self.connection.delete_security_group(self.name)
 
74
 
 
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)
 
83
 
 
84
    def remove_rule(self, ip_protocol, from_port, to_port,
 
85
                    src_group_name, src_group_owner_id, cidr_ip):
 
86
        target_rule = None
 
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:
 
91
                        target_rule = rule
 
92
                        target_grant = None
 
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:
 
97
                                        target_grant = grant
 
98
                        if target_grant:
 
99
                            rule.grants.remove(target_grant)
 
100
        if len(rule.grants) == 0:
 
101
            self.rules.remove(target_rule)
 
102
 
 
103
    def authorize(self, ip_protocol=None, from_port=None, to_port=None,
 
104
                  cidr_ip=None, src_group=None):
 
105
        """
 
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.
 
111
        
 
112
        :type ip_protocol: string
 
113
        :param ip_protocol: Either tcp | udp | icmp
 
114
 
 
115
        :type from_port: int
 
116
        :param from_port: The beginning port number you are enabling
 
117
 
 
118
        :type to_port: int
 
119
        :param to_port: The ending port number you are enabling
 
120
 
 
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
 
124
 
 
125
        :type src_group: :class:`boto.ec2.securitygroup.SecurityGroup` or
 
126
                         :class:`boto.ec2.securitygroup.GroupOrCIDR`
 
127
                         
 
128
        :rtype: bool
 
129
        :return: True if successful.
 
130
        """
 
131
        if src_group:
 
132
            from_port = None
 
133
            to_port = None
 
134
            cidr_ip = None
 
135
            ip_protocol = None
 
136
            src_group_name = src_group.name
 
137
            src_group_owner_id = src_group.owner_id
 
138
        else:
 
139
            src_group_name = None
 
140
            src_group_owner_id = None
 
141
        status = self.connection.authorize_security_group(self.name,
 
142
                                                          src_group_name,
 
143
                                                          src_group_owner_id,
 
144
                                                          ip_protocol,
 
145
                                                          from_port,
 
146
                                                          to_port,
 
147
                                                          cidr_ip)
 
148
        if status:
 
149
            self.add_rule(ip_protocol, from_port, to_port, src_group_name,
 
150
                          src_group_owner_id, cidr_ip)
 
151
        return status
 
152
 
 
153
    def revoke(self, ip_protocol=None, from_port=None, to_port=None,
 
154
               cidr_ip=None, src_group=None):
 
155
        if src_group:
 
156
            from_port=None
 
157
            to_port=None
 
158
            cidr_ip=None
 
159
            ip_protocol = None
 
160
            src_group_name = src_group.name
 
161
            src_group_owner_id = src_group.owner_id
 
162
        else:
 
163
            src_group_name = None
 
164
            src_group_owner_id = None
 
165
        status = self.connection.revoke_security_group(self.name,
 
166
                                                       src_group_name,
 
167
                                                       src_group_owner_id,
 
168
                                                       ip_protocol,
 
169
                                                       from_port,
 
170
                                                       to_port,
 
171
                                                       cidr_ip)
 
172
        if status:
 
173
            self.remove_rule(ip_protocol, from_port, to_port, src_group_name,
 
174
                             src_group_owner_id, cidr_ip)
 
175
        return status
 
176
 
 
177
    def copy_to_region(self, region, name=None):
 
178
        """
 
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
 
182
        operation.
 
183
 
 
184
        :type region: :class:`boto.ec2.regioninfo.RegionInfo`
 
185
        :param region: The region to which this security group will be copied.
 
186
 
 
187
        :type name: string
 
188
        :param name: The name of the copy.  If not supplied, the copy
 
189
                     will have the same name as this security group.
 
190
        
 
191
        :rtype: :class:`boto.ec2.securitygroup.SecurityGroup`
 
192
        :return: The new security group.
 
193
        """
 
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)
 
199
        source_groups = []
 
200
        for rule in self.rules:
 
201
            grant = rule.grants[0]
 
202
            if grant.name:
 
203
                if grant.name not in source_groups:
 
204
                    source_groups.append(grant.name)
 
205
                    sg.authorize(None, None, None, None, grant)
 
206
            else:
 
207
                sg.authorize(rule.ip_protocol, rule.from_port, rule.to_port,
 
208
                             grant.cidr_ip)
 
209
        return sg
 
210
 
 
211
    def instances(self):
 
212
        instances = []
 
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]
 
216
            if uses_group:
 
217
                instances.extend(reservation.instances)
 
218
        return instances
 
219
 
 
220
class IPPermissions:
 
221
 
 
222
    def __init__(self, parent=None):
 
223
        self.parent = parent
 
224
        self.ip_protocol = None
 
225
        self.from_port = None
 
226
        self.to_port = None
 
227
        self.grants = []
 
228
 
 
229
    def __repr__(self):
 
230
        return 'IPPermissions:%s(%s-%s)' % (self.ip_protocol,
 
231
                                            self.from_port, self.to_port)
 
232
 
 
233
    def startElement(self, name, attrs, connection):
 
234
        if name == 'item':
 
235
            self.grants.append(GroupOrCIDR(self))
 
236
            return self.grants[-1]
 
237
        return None
 
238
 
 
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':
 
245
            self.to_port = value
 
246
        else:
 
247
            setattr(self, name, value)
 
248
 
 
249
    def add_grant(self, name=None, owner_id=None, cidr_ip=None):
 
250
        grant = GroupOrCIDR(self)
 
251
        grant.owner_id = owner_id
 
252
        grant.name = name
 
253
        grant.cidr_ip = cidr_ip
 
254
        self.grants.append(grant)
 
255
        return grant
 
256
 
 
257
class GroupOrCIDR:
 
258
 
 
259
    def __init__(self, parent=None):
 
260
        self.owner_id = None
 
261
        self.name = None
 
262
        self.cidr_ip = None
 
263
 
 
264
    def __repr__(self):
 
265
        if self.cidr_ip:
 
266
            return '%s' % self.cidr_ip
 
267
        else:
 
268
            return '%s-%s' % (self.name, self.owner_id)
 
269
 
 
270
    def startElement(self, name, attrs, connection):
 
271
        return None
 
272
 
 
273
    def endElement(self, name, value, connection):
 
274
        if name == 'userId':
 
275
            self.owner_id = value
 
276
        elif name == 'groupName':
 
277
            self.name = value
 
278
        if name == 'cidrIp':
 
279
            self.cidr_ip = value
 
280
        else:
 
281
            setattr(self, name, value)
 
282