Merge lp:~anso/nova/ec2-security-groups into lp:~soren/nova/ec2-security-groups
- ec2-security-groups
- Merge into 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 |
Related bugs: |
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.
Commit message
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
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.
- 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', |
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_(SecurityG roup.id == SecurityGroupIn stanceAssociati on.security_ group_id, " stanceAssociati on.instance_ id," deleted == False,"
220 + "Instance.id == SecurityGroupIn
221 + "SecurityGroup.
222 + "Instance.deleted == False)",
and
231 + primaryjoin= "and_(SecurityG roupIngressRule .parent_ group_id == SecurityGroup.id," ngressRule. deleted == False)")
232 + "SecurityGroupI