Merge lp:~anso/nova/ec2-security-groups into lp:~soren/nova/ec2-security-groups

Proposed by Vish Ishaya
Status: Superseded
Proposed branch: lp:~anso/nova/ec2-security-groups
Merge into: lp:~soren/nova/ec2-security-groups
Prerequisite: lp:~hudson-openstack/nova/trunk
Diff against target: 302 lines (+63/-52)
5 files modified
nova/api/ec2/cloud.py (+12/-14)
nova/db/api.py (+1/-1)
nova/db/sqlalchemy/api.py (+31/-23)
nova/db/sqlalchemy/models.py (+18/-13)
nova/tests/virt_unittest.py (+1/-1)
To merge this branch: bzr merge lp:~anso/nova/ec2-security-groups
Reviewer Review Type Date Requested Status
Devin Carlen (community) Needs Information
Review via email: mp+36974@code.launchpad.net

This proposal has been superseded by a proposal from 2010-09-29.

Description of the change

Fixes deleted objects showing in relations and a few issues with too many rules getting revoked.

To post a comment you must log in.
Revision history for this message
Devin Carlen (devcamcar) wrote :

Looks good except the syntax of the primaryjoins and secondaryjoins is strange. What's with the double quotes? It looks unnecessary based on the sqlalchemy docs, which gives this example of using primary join:

primaryjoin=and_(users_table.c.user_id==addresses_table.c.user_id,
                addresses_table.c.city=='Boston'))

Examples from patch:

219 + secondaryjoin="and_(SecurityGroup.id == SecurityGroupInstanceAssociation.security_group_id,"
220 + "Instance.id == SecurityGroupInstanceAssociation.instance_id,"
221 + "SecurityGroup.deleted == False,"
222 + "Instance.deleted == False)",

and

231 + primaryjoin="and_(SecurityGroupIngressRule.parent_group_id == SecurityGroup.id,"
232 + "SecurityGroupIngressRule.deleted == False)")

review: Needs Information
Revision history for this message
Vish Ishaya (vishvananda) wrote :

the primary and secondary were wrong, the quotes is fine though. If you surround it in quotes, you can refer to tables that haven't been defined yet or are in the process of being defined. Reproposing.

lp:~anso/nova/ec2-security-groups updated
318. By Vish Ishaya

fix ordering of rules to actually allow out and drop in

319. By Vish Ishaya

show project ids for groups instead of user ids

320. By Todd Willey

Merge to latest.

Unmerged revisions

320. By Todd Willey

Merge to latest.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/api/ec2/cloud.py'
2--- nova/api/ec2/cloud.py 2010-09-29 17:25:57 +0000
3+++ nova/api/ec2/cloud.py 2010-09-29 17:25:57 +0000
4@@ -296,7 +296,7 @@
5 db.security_group_get_by_name(context,
6 source_project_id,
7 source_security_group_name)
8- values['group_id'] = source_security_group.id
9+ values['group_id'] = source_security_group['id']
10 elif cidr_ip:
11 # If this fails, it throws an exception. This is what we want.
12 IPy.IP(cidr_ip)
13@@ -333,17 +333,19 @@
14 group_name)
15
16 criteria = self._authorize_revoke_rule_args_to_dict(context, **kwargs)
17+ if criteria == None:
18+ raise exception.ApiError("No rule for the specified parameters.")
19
20 for rule in security_group.rules:
21+ match = True
22 for (k,v) in criteria.iteritems():
23 if getattr(rule, k, False) != v:
24- break
25- # If we make it here, we have a match
26- db.security_group_rule_destroy(context, rule.id)
27-
28- self._trigger_refresh_security_group(security_group)
29-
30- return True
31+ match = False
32+ if match:
33+ db.security_group_rule_destroy(context, rule['id'])
34+ self._trigger_refresh_security_group(security_group)
35+ return True
36+ raise exception.ApiError("No rule for the specified parameters.")
37
38 # TODO(soren): Dupe detection. Adding the same rule twice actually
39 # adds the same rule twice to the rule set, which is
40@@ -387,7 +389,7 @@
41
42 def create_security_group(self, context, group_name, group_description):
43 self._ensure_default_security_group(context)
44- if db.securitygroup_exists(context, context.project.id, group_name):
45+ if db.security_group_exists(context, context.project.id, group_name):
46 raise exception.ApiError('group %s already exists' % group_name)
47
48 group = {'user_id' : context.user.id,
49@@ -779,15 +781,11 @@
50 base_options['project_id'] = context.project.id
51 base_options['user_data'] = kwargs.get('user_data', '')
52
53- type_data = INSTANCE_TYPES[instance_type]
54- base_options['instance_type'] = instance_type
55-<<<<<<< TREE
56-=======
57 base_options['display_name'] = kwargs.get('display_name')
58 base_options['display_description'] = kwargs.get('display_description')
59
60 type_data = INSTANCE_TYPES[instance_type]
61->>>>>>> MERGE-SOURCE
62+ base_options['instance_type'] = instance_type
63 base_options['memory_mb'] = type_data['memory_mb']
64 base_options['vcpus'] = type_data['vcpus']
65 base_options['local_gb'] = type_data['local_gb']
66
67=== modified file 'nova/db/api.py'
68--- nova/db/api.py 2010-09-29 17:25:57 +0000
69+++ nova/db/api.py 2010-09-29 17:25:57 +0000
70@@ -600,7 +600,7 @@
71 return IMPL.security_group_get_by_instance(context, instance_id)
72
73
74-def securitygroup_exists(context, project_id, group_name):
75+def security_group_exists(context, project_id, group_name):
76 """Indicates if a group name exists in a project"""
77 return IMPL.security_group_exists(context, project_id, group_name)
78
79
80=== modified file 'nova/db/sqlalchemy/api.py'
81--- nova/db/sqlalchemy/api.py 2010-09-29 17:25:57 +0000
82+++ nova/db/sqlalchemy/api.py 2010-09-29 17:25:57 +0000
83@@ -28,14 +28,9 @@
84 from nova.db.sqlalchemy import models
85 from nova.db.sqlalchemy.session import get_session
86 from sqlalchemy import or_
87-<<<<<<< TREE
88-from sqlalchemy.orm import eagerload, joinedload_all
89-from sqlalchemy.sql import func
90-=======
91 from sqlalchemy.exc import IntegrityError
92 from sqlalchemy.orm import joinedload_all
93 from sqlalchemy.sql import exists, func
94->>>>>>> MERGE-SOURCE
95
96 FLAGS = flags.FLAGS
97
98@@ -415,8 +410,17 @@
99
100
101 def instance_get(context, instance_id):
102- return models.Instance().find(instance_id, deleted=_deleted(context),
103- options=eagerload('security_groups'))
104+ session = get_session()
105+ instance_ref = session.query(models.Instance
106+ ).filter_by(id=instance_id
107+ ).filter_by(deleted=_deleted(context)
108+ ).options(joinedload_all('security_groups')
109+ ).options(joinedload_all('fixed_ip.floating_ips')
110+ ).first()
111+ if not instance_ref:
112+ raise exception.NotFound('Instance %s not found' % (instance_id))
113+
114+ return instance_ref
115
116
117 def instance_get_all(context):
118@@ -950,16 +954,18 @@
119 def security_group_get_all(_context):
120 session = get_session()
121 return session.query(models.SecurityGroup
122- ).options(eagerload('rules')
123 ).filter_by(deleted=False
124+ ).options(joinedload_all('rules')
125 ).all()
126
127
128 def security_group_get(_context, security_group_id):
129 session = get_session()
130 result = session.query(models.SecurityGroup
131- ).options(eagerload('rules')
132- ).get(security_group_id)
133+ ).filter_by(deleted=False
134+ ).filter_by(id=security_group_id
135+ ).options(joinedload_all('rules')
136+ ).first()
137 if not result:
138 raise exception.NotFound("No secuity group with id %s" %
139 security_group_id)
140@@ -968,36 +974,38 @@
141
142 def security_group_get_by_name(context, project_id, group_name):
143 session = get_session()
144- group_ref = session.query(models.SecurityGroup
145- ).options(eagerload('rules')
146- ).options(eagerload('instances')
147+ result = session.query(models.SecurityGroup
148 ).filter_by(project_id=project_id
149 ).filter_by(name=group_name
150 ).filter_by(deleted=False
151+ ).options(joinedload_all('rules')
152+ ).options(joinedload_all('instances')
153 ).first()
154- if not group_ref:
155+ if not result:
156 raise exception.NotFound(
157 'No security group named %s for project: %s' \
158 % (group_name, project_id))
159- return group_ref
160+ return result
161
162
163 def security_group_get_by_project(_context, project_id):
164 session = get_session()
165 return session.query(models.SecurityGroup
166- ).options(eagerload('rules')
167 ).filter_by(project_id=project_id
168 ).filter_by(deleted=False
169+ ).options(joinedload_all('rules')
170 ).all()
171
172
173 def security_group_get_by_instance(_context, instance_id):
174 session = get_session()
175- with session.begin():
176- return session.query(models.Instance
177- ).join(models.Instance.security_groups
178- ).filter_by(deleted=False
179- ).all()
180+ return session.query(models.SecurityGroup
181+ ).filter_by(deleted=False
182+ ).options(joinedload_all('rules')
183+ ).join(models.SecurityGroup.instances
184+ ).filter_by(id=instance_id
185+ ).filter_by(deleted=False
186+ ).all()
187
188
189 def security_group_exists(_context, project_id, group_name):
190@@ -1023,7 +1031,7 @@
191 session = get_session()
192 with session.begin():
193 # TODO(vish): do we have to use sql here?
194- session.execute('update security_group set deleted=1 where id=:id',
195+ session.execute('update security_groups set deleted=1 where id=:id',
196 {'id': security_group_id})
197 session.execute('update security_group_rules set deleted=1 '
198 'where group_id=:id',
199@@ -1033,7 +1041,7 @@
200 session = get_session()
201 with session.begin():
202 # TODO(vish): do we have to use sql here?
203- session.execute('update security_group set deleted=1')
204+ session.execute('update security_groups set deleted=1')
205 session.execute('update security_group_rules set deleted=1')
206
207 ###################
208
209=== modified file 'nova/db/sqlalchemy/models.py'
210--- nova/db/sqlalchemy/models.py 2010-09-29 17:25:57 +0000
211+++ nova/db/sqlalchemy/models.py 2010-09-29 17:25:57 +0000
212@@ -25,7 +25,7 @@
213
214 # TODO(vish): clean up these imports
215 from sqlalchemy.orm import relationship, backref, exc, object_mapper
216-from sqlalchemy import Column, Integer, String, Table
217+from sqlalchemy import Column, Integer, String
218 from sqlalchemy import ForeignKey, DateTime, Boolean, Text
219 from sqlalchemy.ext.declarative import declarative_base
220
221@@ -340,16 +340,16 @@
222 uselist=False))
223
224
225-security_group_instance_association = Table('security_group_instance_association',
226- BASE.metadata,
227- Column('security_group_id', Integer,
228- ForeignKey('security_group.id')),
229- Column('instance_id', Integer,
230- ForeignKey('instances.id')))
231+class SecurityGroupInstanceAssociation(BASE, NovaBase):
232+ __tablename__ = 'security_group_instance_association'
233+ id = Column(Integer, primary_key=True)
234+ security_group_id = Column(Integer, ForeignKey('security_groups.id'))
235+ instance_id = Column(Integer, ForeignKey('instances.id'))
236+
237
238 class SecurityGroup(BASE, NovaBase):
239 """Represents a security group"""
240- __tablename__ = 'security_group'
241+ __tablename__ = 'security_groups'
242 id = Column(Integer, primary_key=True)
243
244 name = Column(String(255))
245@@ -358,7 +358,11 @@
246 project_id = Column(String(255))
247
248 instances = relationship(Instance,
249- secondary=security_group_instance_association,
250+ secondary="security_group_instance_association",
251+ primaryjoin="and_(SecurityGroup.id == SecurityGroupInstanceAssociation.security_group_id,"
252+ "SecurityGroup.deleted == False)",
253+ secondaryjoin="and_(SecurityGroupInstanceAssociation.instance_id == Instance.id,"
254+ "Instance.deleted == False)",
255 backref='security_groups')
256
257 @property
258@@ -375,10 +379,11 @@
259 __tablename__ = 'security_group_rules'
260 id = Column(Integer, primary_key=True)
261
262- parent_group_id = Column(Integer, ForeignKey('security_group.id'))
263+ parent_group_id = Column(Integer, ForeignKey('security_groups.id'))
264 parent_group = relationship("SecurityGroup", backref="rules",
265 foreign_keys=parent_group_id,
266- primaryjoin=parent_group_id==SecurityGroup.id)
267+ primaryjoin="and_(SecurityGroupIngressRule.parent_group_id == SecurityGroup.id,"
268+ "SecurityGroupIngressRule.deleted == False)")
269
270 protocol = Column(String(5)) # "tcp", "udp", or "icmp"
271 from_port = Column(Integer)
272@@ -387,7 +392,7 @@
273
274 # Note: This is not the parent SecurityGroup. It's SecurityGroup we're
275 # granting access for.
276- group_id = Column(Integer, ForeignKey('security_group.id'))
277+ group_id = Column(Integer, ForeignKey('security_groups.id'))
278
279
280 class KeyPair(BASE, NovaBase):
281@@ -541,7 +546,7 @@
282 from sqlalchemy import create_engine
283 models = (Service, Instance, Volume, ExportDevice, FixedIp, FloatingIp,
284 Network, NetworkIndex, SecurityGroup, SecurityGroupIngressRule,
285- AuthToken) # , Image, Host
286+ SecurityGroupInstanceAssociation, AuthToken) # , Image, Host
287 engine = create_engine(FLAGS.sql_connection, echo=False)
288 for model in models:
289 model.metadata.create_all(engine)
290
291=== modified file 'nova/tests/virt_unittest.py'
292--- nova/tests/virt_unittest.py 2010-09-29 07:46:37 +0000
293+++ nova/tests/virt_unittest.py 2010-09-29 17:25:57 +0000
294@@ -185,7 +185,7 @@
295 inst_id = instance_ref['id']
296
297 def _ensure_all_called(_):
298- instance_filter = 'nova-instance-%s' % instance_ref['str_id']
299+ instance_filter = 'nova-instance-%s' % instance_ref['name']
300 secgroup_filter = 'nova-secgroup-%s' % self.security_group['id']
301 for required in [secgroup_filter, 'allow-dhcp-server',
302 'no-arp-spoofing', 'no-ip-spoofing',

Subscribers

People subscribed via source and target branches