From bd07d6b3b3e9ed3ef3e65e99b628c8b1aaf2f82c Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Thu, 9 Sep 2010 12:35:46 +0200 Subject: Alright, first hole poked all the way through. We can now create security groups and read them back. --- nova/db/api.py | 22 ++++++++++++++++++ nova/db/sqlalchemy/api.py | 38 +++++++++++++++++++++++++++++++ nova/db/sqlalchemy/models.py | 54 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 113 insertions(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index b49707392..b67e3afe0 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -442,3 +442,25 @@ def volume_update(context, volume_id, values): """ return IMPL.volume_update(context, volume_id, values) + +#################### + + +def security_group_create(context, values): + """Create a new security group""" + return IMPL.security_group_create(context, values) + + +def security_group_get_by_instance(context, instance_id): + """Get security groups to which the instance is assigned""" + return IMPL.security_group_get_by_instance(context, instance_id) + + +def security_group_get_by_user(context, user_id): + """Get security groups owned by the given user""" + return IMPL.security_group_get_by_user(context, user_id) + + +def security_group_destroy(context, security_group_id): + """Deletes a security group""" + return IMPL.security_group_destroy(context, security_group_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 5172b87b3..d790d3fac 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -581,3 +581,41 @@ def volume_update(context, volume_id, values): for (key, value) in values.iteritems(): volume_ref[key] = value volume_ref.save() + + +################### + + +def security_group_create(_context, values): + security_group_ref = models.SecurityGroup() + for (key, value) in values.iteritems(): + security_group_ref[key] = value + security_group_ref.save() + return security_group_ref + + +def security_group_get_by_instance(_context, instance_id): + with managed_session() as session: + return session.query(models.Instance) \ + .get(instance_id) \ + .security_groups \ + .all() + + +def security_group_get_by_user(_context, user_id): + with managed_session() as session: + return session.query(models.SecurityGroup) \ + .filter_by(user_id=user_id) \ + .filter_by(deleted=False) \ + .all() + +def security_group_destroy(_context, security_group_id): + with managed_session() as session: + security_group = session.query(models.SecurityGroup) \ + .get(security_group_id) + security_group.delete(session=session) + +def security_group_get_all(_context): + return models.SecurityGroup.all() + + diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 310d4640e..28c25bfbc 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -26,7 +26,7 @@ import datetime # TODO(vish): clean up these imports from sqlalchemy.orm import relationship, backref, validates, exc from sqlalchemy.sql import func -from sqlalchemy import Column, Integer, String +from sqlalchemy import Column, Integer, String, Table from sqlalchemy import ForeignKey, DateTime, Boolean, Text from sqlalchemy.ext.declarative import declarative_base @@ -292,6 +292,58 @@ class ExportDevice(BASE, NovaBase): uselist=False)) +security_group_instance_association = Table('security_group_instance_association', + BASE.metadata, + Column('security_group_id', Integer, + ForeignKey('security_group.id')), + Column('instance_id', Integer, + ForeignKey('instances.id'))) + +class SecurityGroup(BASE, NovaBase): + """Represents a security group""" + __tablename__ = 'security_group' + id = Column(Integer, primary_key=True) + + name = Column(String(255)) + description = Column(String(255)) + + user_id = Column(String(255)) + project_id = Column(String(255)) + + instances = relationship(Instance, + secondary=security_group_instance_association, + backref='security_groups') + + @property + def user(self): + return auth.manager.AuthManager().get_user(self.user_id) + + @property + def project(self): + return auth.manager.AuthManager().get_project(self.project_id) + + +class SecurityGroupIngressRule(BASE, NovaBase): + """Represents a rule in a security group""" + __tablename__ = 'security_group_rules' + id = Column(Integer, primary_key=True) + + parent_security_group = Column(Integer, ForeignKey('security_group.id')) + protocol = Column(String(5)) # "tcp", "udp", or "icmp" + fromport = Column(Integer) + toport = Column(Integer) + + # Note: This is not the parent SecurityGroup's owner. It's the owner of + # the SecurityGroup we're granting access. + user_id = Column(String(255)) + group_id = Column(Integer, ForeignKey('security_group.id')) + + @property + def user(self): + return auth.manager.AuthManager().get_user(self.user_id) + + cidr = Column(String(255)) + class Network(BASE, NovaBase): """Represents a network""" __tablename__ = 'networks' -- cgit From bd7ac72b9774a181e51dde5dff09ed4c47b556a7 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Thu, 9 Sep 2010 15:13:04 +0200 Subject: AuthorizeSecurityGroupIngress now works. --- nova/db/api.py | 13 +++++++++++++ nova/db/sqlalchemy/api.py | 19 +++++++++++++++++++ nova/db/sqlalchemy/models.py | 9 ++++----- 3 files changed, 36 insertions(+), 5 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index b67e3afe0..af574d6de 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -461,6 +461,19 @@ def security_group_get_by_user(context, user_id): return IMPL.security_group_get_by_user(context, user_id) +def security_group_get_by_user_and_name(context, user_id, name): + """Get user's named security group""" + return IMPL.security_group_get_by_user_and_name(context, user_id, name) + + def security_group_destroy(context, security_group_id): """Deletes a security group""" return IMPL.security_group_destroy(context, security_group_id) + + +#################### + + +def security_group_rule_create(context, values): + """Create a new security group""" + return IMPL.security_group_rule_create(context, values) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d790d3fac..c8d852f9d 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -609,6 +609,14 @@ def security_group_get_by_user(_context, user_id): .filter_by(deleted=False) \ .all() +def security_group_get_by_user_and_name(_context, user_id, name): + with managed_session() as session: + return session.query(models.SecurityGroup) \ + .filter_by(user_id=user_id) \ + .filter_by(name=name) \ + .filter_by(deleted=False) \ + .one() + def security_group_destroy(_context, security_group_id): with managed_session() as session: security_group = session.query(models.SecurityGroup) \ @@ -619,3 +627,14 @@ def security_group_get_all(_context): return models.SecurityGroup.all() + + +################### + + +def security_group_rule_create(_context, values): + security_group_rule_ref = models.SecurityGroupIngressRule() + for (key, value) in values.iteritems(): + security_group_rule_ref[key] = value + security_group_rule_ref.save() + return security_group_rule_ref diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 28c25bfbc..330262a88 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -330,12 +330,11 @@ class SecurityGroupIngressRule(BASE, NovaBase): parent_security_group = Column(Integer, ForeignKey('security_group.id')) protocol = Column(String(5)) # "tcp", "udp", or "icmp" - fromport = Column(Integer) - toport = Column(Integer) + from_port = Column(Integer) + to_port = Column(Integer) - # Note: This is not the parent SecurityGroup's owner. It's the owner of - # the SecurityGroup we're granting access. - user_id = Column(String(255)) + # Note: This is not the parent SecurityGroup. It's SecurityGroup we're + # granting access for. group_id = Column(Integer, ForeignKey('security_group.id')) @property -- cgit From 59a959299d7883c48626d8d5630974d718194960 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Thu, 9 Sep 2010 17:35:02 +0200 Subject: Authorize and Revoke access now works. --- nova/db/api.py | 9 +++++++++ nova/db/sqlalchemy/api.py | 8 ++++++++ nova/db/sqlalchemy/models.py | 7 +++++-- 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index af574d6de..63ead04e0 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -477,3 +477,12 @@ def security_group_destroy(context, security_group_id): def security_group_rule_create(context, values): """Create a new security group""" return IMPL.security_group_rule_create(context, values) + + +def security_group_rule_get_by_security_group(context, security_group_id): + """Get all rules for a a given security group""" + return IMPL.security_group_rule_get_by_security_group(context, security_group_id) + +def security_group_rule_destroy(context, security_group_rule_id): + """Deletes a security group rule""" + return IMPL.security_group_rule_destroy(context, security_group_rule_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index c8d852f9d..2db876154 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -25,6 +25,7 @@ from nova import flags from nova.db.sqlalchemy import models from nova.db.sqlalchemy.session import managed_session from sqlalchemy import or_ +from sqlalchemy.orm import eagerload FLAGS = flags.FLAGS @@ -615,6 +616,7 @@ def security_group_get_by_user_and_name(_context, user_id, name): .filter_by(user_id=user_id) \ .filter_by(name=name) \ .filter_by(deleted=False) \ + .options(eagerload('rules')) \ .one() def security_group_destroy(_context, security_group_id): @@ -638,3 +640,9 @@ def security_group_rule_create(_context, values): security_group_rule_ref[key] = value security_group_rule_ref.save() return security_group_rule_ref + +def security_group_rule_destroy(_context, security_group_rule_id): + with managed_session() as session: + security_group_rule = session.query(models.SecurityGroupIngressRule) \ + .get(security_group_rule_id) + security_group_rule.delete(session=session) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 330262a88..d177688d8 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -328,14 +328,17 @@ class SecurityGroupIngressRule(BASE, NovaBase): __tablename__ = 'security_group_rules' id = Column(Integer, primary_key=True) - parent_security_group = Column(Integer, ForeignKey('security_group.id')) + parent_group_id = Column(Integer, ForeignKey('security_group.id')) + parent_group = relationship("SecurityGroup", backref="rules", foreign_keys=parent_group_id) +# primaryjoin=SecurityGroup().id==parent_group_id) + protocol = Column(String(5)) # "tcp", "udp", or "icmp" from_port = Column(Integer) to_port = Column(Integer) # Note: This is not the parent SecurityGroup. It's SecurityGroup we're # granting access for. - group_id = Column(Integer, ForeignKey('security_group.id')) +# group_id = Column(Integer, ForeignKey('security_group.id')) @property def user(self): -- cgit From ecbbfa343edf0ca0e82b35dc655fa23701bbdf22 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Fri, 10 Sep 2010 11:47:06 +0200 Subject: Create and delete security groups works. Adding and revoking rules works. DescribeSecurityGroups returns the groups and rules. So, the API seems to be done. Yay. --- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 7 +++++++ nova/db/sqlalchemy/models.py | 6 +++--- 3 files changed, 15 insertions(+), 3 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 63ead04e0..c7a6da183 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -451,6 +451,11 @@ def security_group_create(context, values): return IMPL.security_group_create(context, values) +def security_group_get_by_id(context, security_group_id): + """Get security group by its internal id""" + return IMPL.security_group_get_by_id(context, security_group_id) + + def security_group_get_by_instance(context, instance_id): """Get security groups to which the instance is assigned""" return IMPL.security_group_get_by_instance(context, instance_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 2db876154..4027e901c 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -595,6 +595,12 @@ def security_group_create(_context, values): return security_group_ref +def security_group_get_by_id(_context, security_group_id): + with managed_session() as session: + return session.query(models.SecurityGroup) \ + .get(security_group_id) + + def security_group_get_by_instance(_context, instance_id): with managed_session() as session: return session.query(models.Instance) \ @@ -608,6 +614,7 @@ def security_group_get_by_user(_context, user_id): return session.query(models.SecurityGroup) \ .filter_by(user_id=user_id) \ .filter_by(deleted=False) \ + .options(eagerload('rules')) \ .all() def security_group_get_by_user_and_name(_context, user_id, name): diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index d177688d8..27c8e4d4c 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -329,8 +329,8 @@ class SecurityGroupIngressRule(BASE, NovaBase): id = Column(Integer, primary_key=True) parent_group_id = Column(Integer, ForeignKey('security_group.id')) - parent_group = relationship("SecurityGroup", backref="rules", foreign_keys=parent_group_id) -# primaryjoin=SecurityGroup().id==parent_group_id) + parent_group = relationship("SecurityGroup", backref="rules", foreign_keys=parent_group_id, + primaryjoin=parent_group_id==SecurityGroup.id) protocol = Column(String(5)) # "tcp", "udp", or "icmp" from_port = Column(Integer) @@ -338,7 +338,7 @@ class SecurityGroupIngressRule(BASE, NovaBase): # Note: This is not the parent SecurityGroup. It's SecurityGroup we're # granting access for. -# group_id = Column(Integer, ForeignKey('security_group.id')) + group_id = Column(Integer, ForeignKey('security_group.id')) @property def user(self): -- cgit From c3dd0aa79d982d8f34172e6023d4b632ea23f2b9 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Fri, 10 Sep 2010 14:56:36 +0200 Subject: First pass of nwfilter based security group implementation. It is not where it is supposed to be and it does not actually do anything yet. --- nova/db/sqlalchemy/api.py | 1 + 1 file changed, 1 insertion(+) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 4027e901c..622e76cd7 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -598,6 +598,7 @@ def security_group_create(_context, values): def security_group_get_by_id(_context, security_group_id): with managed_session() as session: return session.query(models.SecurityGroup) \ + .options(eagerload('rules')) \ .get(security_group_id) -- cgit From e53676bb32b70ff01ca27c310e558b651590be3d Mon Sep 17 00:00:00 2001 From: Devin Carlen Date: Fri, 10 Sep 2010 15:26:13 -0700 Subject: Refactored to security group api to support projects --- nova/db/api.py | 34 ++++++++++++-------- nova/db/sqlalchemy/api.py | 76 +++++++++++++++++++++++++++----------------- nova/db/sqlalchemy/models.py | 22 ++++++------- 3 files changed, 77 insertions(+), 55 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 2bcf0bd2b..cdbd15486 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -442,33 +442,39 @@ def volume_update(context, volume_id, values): """ return IMPL.volume_update(context, volume_id, values) + #################### -def security_group_create(context, values): - """Create a new security group""" - return IMPL.security_group_create(context, values) +def security_group_get_all(context): + """Get all security groups""" + return IMPL.security_group_get_all(context) -def security_group_get_by_id(context, security_group_id): +def security_group_get(context, security_group_id): """Get security group by its internal id""" - return IMPL.security_group_get_by_id(context, security_group_id) + return IMPL.security_group_get(context, security_group_id) -def security_group_get_by_instance(context, instance_id): - """Get security groups to which the instance is assigned""" - return IMPL.security_group_get_by_instance(context, instance_id) +def security_group_get_by_name(context, project_id, group_name): + """Returns a security group with the specified name from a project""" + return IMPL.securitygroup_get_by_name(context, project_id, group_name) -def security_group_get_by_user(context, user_id): - """Get security groups owned by the given user""" - return IMPL.security_group_get_by_user(context, user_id) +def security_group_get_by_project(context, project_id): + """Get all security groups belonging to a project""" + return IMPL.securitygroup_get_by_project(context, project_id) -def security_group_get_by_user_and_name(context, user_id, name): - """Get user's named security group""" - return IMPL.security_group_get_by_user_and_name(context, user_id, name) +def security_group_get_by_instance(context, instance_id): + """Get security groups to which the instance is assigned""" + return IMPL.security_group_get_by_instance(context, instance_id) + +def security_group_create(context, values): + """Create a new security group""" + return IMPL.security_group_create(context, values) + def security_group_destroy(context, security_group_id): """Deletes a security group""" diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 1c95efd83..61d733940 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -616,20 +616,45 @@ def volume_update(_context, volume_id, values): ################### -def security_group_create(_context, values): - security_group_ref = models.SecurityGroup() - for (key, value) in values.iteritems(): - security_group_ref[key] = value - security_group_ref.save() - return security_group_ref +def security_group_get_all(_context): + session = get_session() + return session.query(models.SecurityGroup + ).options(eagerload('rules') + ).filter_by(deleted=False + ).all() -def security_group_get_by_id(_context, security_group_id): +def security_group_get(_context, security_group_id): session = get_session() with session.begin(): return session.query(models.SecurityGroup + ).options(eagerload('rules') + ).get(security_group_id) + + +def securitygroup_get_by_name(context, project_id, group_name): + session = get_session() + group_ref = session.query(models.SecurityGroup ).options(eagerload('rules') - ).get(security_group_id) + ).filter_by(project_id=project_id + ).filter_by(name=group_name + ).filter_by(deleted=False + ).first() + if not group_ref: + raise exception.NotFound( + 'No security group named %s for project: %s' \ + % (group_name, project_id)) + + return group_ref + + +def securitygroup_get_by_project(_context, project_id): + session = get_session() + return session.query(models.SecurityGroup + ).options(eagerload('rules') + ).filter_by(project_id=project_id + ).filter_by(deleted=False + ).all() def security_group_get_by_instance(_context, instance_id): @@ -638,34 +663,27 @@ def security_group_get_by_instance(_context, instance_id): return session.query(models.Instance ).get(instance_id ).security_groups \ - .all() + .filter_by(deleted=False + ).all() -def security_group_get_by_user(_context, user_id): - session = get_session() - with session.begin(): - return session.query(models.SecurityGroup - ).filter_by(user_id=user_id - ).filter_by(deleted=False - ).options(eagerload('rules') - ).all() +def security_group_create(_context, values): + security_group_ref = models.SecurityGroup() + for (key, value) in values.iteritems(): + security_group_ref[key] = value + security_group_ref.save() + return security_group_ref -def security_group_get_by_user_and_name(_context, user_id, name): - session = get_session() - with session.begin(): - return session.query(models.SecurityGroup - ).filter_by(user_id=user_id - ).filter_by(name=name - ).filter_by(deleted=False - ).options(eagerload('rules') - ).one() def security_group_destroy(_context, security_group_id): session = get_session() with session.begin(): - security_group = session.query(models.SecurityGroup - ).get(security_group_id) - security_group.delete(session=session) + # TODO(vish): do we have to use sql here? + session.execute('update security_group set deleted=1 where id=:id', + {'id': security_group_id}) + session.execute('update security_group_rule set deleted=1 ' + 'where group_id=:id', + {'id': security_group_id}) ################### diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index f27520aa8..3c4b9ddd7 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -306,26 +306,23 @@ class SecurityGroup(BASE, NovaBase): class SecurityGroupIngressRule(BASE, NovaBase): """Represents a rule in a security group""" - __tablename__ = 'security_group_rules' + __tablename__ = 'security_group_rule' id = Column(Integer, primary_key=True) - parent_group_id = Column(Integer, ForeignKey('security_group.id')) - parent_group = relationship("SecurityGroup", backref="rules", foreign_keys=parent_group_id, - primaryjoin=parent_group_id==SecurityGroup.id) + group_id = Column(Integer, ForeignKey('security_group.id')) + group = relationship("SecurityGroup", backref="rules", + foreign_keys=group_id, + primaryjoin=group_id==SecurityGroup.id) protocol = Column(String(5)) # "tcp", "udp", or "icmp" from_port = Column(Integer) to_port = Column(Integer) + cidr = Column(String(255)) # Note: This is not the parent SecurityGroup. It's SecurityGroup we're # granting access for. - group_id = Column(Integer, ForeignKey('security_group.id')) - - @property - def user(self): - return auth.manager.AuthManager().get_user(self.user_id) + source_group_id = Column(Integer, ForeignKey('security_group.id')) - cidr = Column(String(255)) class Network(BASE, NovaBase): """Represents a network""" @@ -430,8 +427,9 @@ class FloatingIp(BASE, NovaBase): def register_models(): """Register Models and create metadata""" from sqlalchemy import create_engine - models = (Service, Instance, Volume, ExportDevice, - FixedIp, FloatingIp, Network, NetworkIndex) # , Image, Host) + models = (Service, Instance, Volume, ExportDevice, FixedIp, FloatingIp, + Network, NetworkIndex, SecurityGroup, SecurityGroupIngressRule) + # , Image, Host engine = create_engine(FLAGS.sql_connection, echo=False) for model in models: model.metadata.create_all(engine) -- cgit From 60b6b06d15ed620cf990db10277c4126b686de80 Mon Sep 17 00:00:00 2001 From: Devin Carlen Date: Fri, 10 Sep 2010 19:19:08 -0700 Subject: Finished security group / project refactor --- nova/db/sqlalchemy/api.py | 2 +- nova/db/sqlalchemy/models.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 61d733940..f3d4b68c4 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -681,7 +681,7 @@ def security_group_destroy(_context, security_group_id): # TODO(vish): do we have to use sql here? session.execute('update security_group set deleted=1 where id=:id', {'id': security_group_id}) - session.execute('update security_group_rule set deleted=1 ' + session.execute('update security_group_rules set deleted=1 ' 'where group_id=:id', {'id': security_group_id}) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 3c4b9ddd7..e79a0415b 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -306,13 +306,13 @@ class SecurityGroup(BASE, NovaBase): class SecurityGroupIngressRule(BASE, NovaBase): """Represents a rule in a security group""" - __tablename__ = 'security_group_rule' + __tablename__ = 'security_group_rules' id = Column(Integer, primary_key=True) - group_id = Column(Integer, ForeignKey('security_group.id')) - group = relationship("SecurityGroup", backref="rules", - foreign_keys=group_id, - primaryjoin=group_id==SecurityGroup.id) + parent_group_id = Column(Integer, ForeignKey('security_group.id')) + parent_group = relationship("SecurityGroup", backref="rules", + foreign_keys=parent_group_id, + primaryjoin=parent_group_id==SecurityGroup.id) protocol = Column(String(5)) # "tcp", "udp", or "icmp" from_port = Column(Integer) @@ -321,7 +321,7 @@ class SecurityGroupIngressRule(BASE, NovaBase): # Note: This is not the parent SecurityGroup. It's SecurityGroup we're # granting access for. - source_group_id = Column(Integer, ForeignKey('security_group.id')) + group_id = Column(Integer, ForeignKey('security_group.id')) class Network(BASE, NovaBase): -- cgit From f24f20948cf7e6cc0e14c2b1fc41a61d8d2fa34c Mon Sep 17 00:00:00 2001 From: Devin Carlen Date: Sat, 11 Sep 2010 11:19:22 -0700 Subject: Security Group API layer cleanup --- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 11 +++++++++++ 2 files changed, 16 insertions(+) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index cdbd15486..cf39438c2 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -471,6 +471,11 @@ def security_group_get_by_instance(context, instance_id): return IMPL.security_group_get_by_instance(context, instance_id) +def securitygroup_exists(context, project_id, group_name): + """Indicates if a group name exists in a project""" + return IMPL.securitygroup_exists(context, project_id, group_name) + + def security_group_create(context, values): """Create a new security group""" return IMPL.security_group_create(context, values) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index f3d4b68c4..513b47bc9 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -667,8 +667,19 @@ def security_group_get_by_instance(_context, instance_id): ).all() +def securitygroup_exists(_context, project_id, group_name): + try: + group = securitygroup_get_by_name(_context, project_id, group_name) + return group != None + except exception.NotFound: + return False + + def security_group_create(_context, values): security_group_ref = models.SecurityGroup() + # FIXME(devcamcar): Unless I do this, rules fails with lazy load exception + # once save() is called. This will get cleaned up in next orm pass. + security_group_ref.rules for (key, value) in values.iteritems(): security_group_ref[key] = value security_group_ref.save() -- cgit From 2a782110bc51f147bdb35264445badac3b3e8e65 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 13 Sep 2010 11:45:28 +0200 Subject: Filters all get defined when running an instance. --- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 16 +++++++++++++++- nova/db/sqlalchemy/models.py | 1 - 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index cf39438c2..1d10b1987 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -244,6 +244,11 @@ def instance_update(context, instance_id, values): return IMPL.instance_update(context, instance_id, values) +def instance_add_security_group(context, instance_id, security_group_id): + """Associate the given security group with the given instance""" + return IMPL.instance_add_security_group(context, instance_id, security_group_id) + + #################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 513b47bc9..11779e30c 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -238,7 +238,10 @@ def instance_destroy(_context, instance_id): def instance_get(_context, instance_id): - return models.Instance.find(instance_id) + session = get_session() + return session.query(models.Instance + ).options(eagerload('security_groups') + ).get(instance_id) def instance_get_all(_context): @@ -317,6 +320,17 @@ def instance_update(_context, instance_id, values): instance_ref.save(session=session) +def instance_add_security_group(context, instance_id, security_group_id): + """Associate the given security group with the given instance""" + session = get_session() + with session.begin(): + instance_ref = models.Instance.find(instance_id, session=session) + security_group_ref = models.SecurityGroup.find(security_group_id, + session=session) + instance_ref.security_groups += [security_group_ref] + instance_ref.save(session=session) + + ################### diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index e79a0415b..424906c1f 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -215,7 +215,6 @@ class Instance(BASE, NovaBase): launch_index = Column(Integer) key_name = Column(String(255)) key_data = Column(Text) - security_group = Column(String(255)) state = Column(Integer) state_description = Column(String(255)) -- cgit From 01a041dd732ae9c56533f6eac25f08c34917d733 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 14 Sep 2010 15:17:52 +0200 Subject: Fix up rule generation. It turns out nwfilter gets very, very wonky indeed if you mix rules and rules. Setting a TCP rule adds an early rule to ebtables that ends up overriding the rules which are last in that table. --- nova/db/sqlalchemy/session.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/session.py b/nova/db/sqlalchemy/session.py index 69a205378..fffbd3443 100644 --- a/nova/db/sqlalchemy/session.py +++ b/nova/db/sqlalchemy/session.py @@ -20,7 +20,7 @@ Session Handling for SQLAlchemy backend """ from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import sessionmaker, scoped_session from nova import flags @@ -36,7 +36,8 @@ def get_session(autocommit=True, expire_on_commit=False): if not _MAKER: if not _ENGINE: _ENGINE = create_engine(FLAGS.sql_connection, echo=False) - _MAKER = sessionmaker(bind=_ENGINE, - autocommit=autocommit, - expire_on_commit=expire_on_commit) - return _MAKER() + _MAKER = scoped_session(sessionmaker(bind=_ENGINE, + autocommit=autocommit, + expire_on_commit=expire_on_commit)) + session = _MAKER() + return session -- cgit From 9196b74080d5effd8dcfacce9de7d2dd37fcba1b Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Wed, 15 Sep 2010 14:04:07 +0200 Subject: Clean up use of ORM to remove the need for scoped_session. --- nova/db/api.py | 6 +++--- nova/db/sqlalchemy/api.py | 9 +++++---- nova/db/sqlalchemy/session.py | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 1d10b1987..fa937dab2 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -463,12 +463,12 @@ def security_group_get(context, security_group_id): def security_group_get_by_name(context, project_id, group_name): """Returns a security group with the specified name from a project""" - return IMPL.securitygroup_get_by_name(context, project_id, group_name) + return IMPL.security_group_get_by_name(context, project_id, group_name) def security_group_get_by_project(context, project_id): """Get all security groups belonging to a project""" - return IMPL.securitygroup_get_by_project(context, project_id) + return IMPL.security_group_get_by_project(context, project_id) def security_group_get_by_instance(context, instance_id): @@ -478,7 +478,7 @@ def security_group_get_by_instance(context, instance_id): def securitygroup_exists(context, project_id, group_name): """Indicates if a group name exists in a project""" - return IMPL.securitygroup_exists(context, project_id, group_name) + return IMPL.security_group_exists(context, project_id, group_name) def security_group_create(context, values): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 11779e30c..038bb7f23 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -646,10 +646,11 @@ def security_group_get(_context, security_group_id): ).get(security_group_id) -def securitygroup_get_by_name(context, project_id, group_name): +def security_group_get_by_name(context, project_id, group_name): session = get_session() group_ref = session.query(models.SecurityGroup ).options(eagerload('rules') + ).options(eagerload('instances') ).filter_by(project_id=project_id ).filter_by(name=group_name ).filter_by(deleted=False @@ -662,7 +663,7 @@ def securitygroup_get_by_name(context, project_id, group_name): return group_ref -def securitygroup_get_by_project(_context, project_id): +def security_group_get_by_project(_context, project_id): session = get_session() return session.query(models.SecurityGroup ).options(eagerload('rules') @@ -681,9 +682,9 @@ def security_group_get_by_instance(_context, instance_id): ).all() -def securitygroup_exists(_context, project_id, group_name): +def security_group_exists(_context, project_id, group_name): try: - group = securitygroup_get_by_name(_context, project_id, group_name) + group = security_group_get_by_name(_context, project_id, group_name) return group != None except exception.NotFound: return False diff --git a/nova/db/sqlalchemy/session.py b/nova/db/sqlalchemy/session.py index fffbd3443..826754f6a 100644 --- a/nova/db/sqlalchemy/session.py +++ b/nova/db/sqlalchemy/session.py @@ -20,7 +20,7 @@ Session Handling for SQLAlchemy backend """ from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker, scoped_session +from sqlalchemy.orm import sessionmaker from nova import flags @@ -36,7 +36,7 @@ def get_session(autocommit=True, expire_on_commit=False): if not _MAKER: if not _ENGINE: _ENGINE = create_engine(FLAGS.sql_connection, echo=False) - _MAKER = scoped_session(sessionmaker(bind=_ENGINE, + _MAKER = (sessionmaker(bind=_ENGINE, autocommit=autocommit, expire_on_commit=expire_on_commit)) session = _MAKER() -- cgit From 169ac33d89e0721c3e5229f2c58b799b64f1b51d Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 21 Sep 2010 16:32:07 -0700 Subject: typo in instance_get --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 5ceb4c814..90c7938df 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -380,7 +380,7 @@ def instance_destroy(_context, instance_id): def instance_get(context, instance_id): session = get_session() - result = session.query(models.FixedIp + result = session.query(models.Instance ).options(eagerload('security_groups') ).filter_by(instance_id=instance_id ).filter_by(deleted=_deleted(context) -- cgit From e78273f72640eb9cbd1797d8d66dc41dcb96bee0 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 21 Sep 2010 16:43:32 -0700 Subject: typo in instance_get --- nova/db/sqlalchemy/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 90c7938df..420fd4a4a 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -382,7 +382,7 @@ def instance_get(context, instance_id): session = get_session() result = session.query(models.Instance ).options(eagerload('security_groups') - ).filter_by(instance_id=instance_id + ).filter_by(id=instance_id ).filter_by(deleted=_deleted(context) ).first() if not result: -- cgit From e4cb0d3a93ddc4cae40c4a8c570c7e7d2a0061ff Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 28 Sep 2010 10:34:32 -0700 Subject: get rid of network indexes and make networks into a pool --- nova/db/api.py | 35 +++++++++-------- nova/db/sqlalchemy/api.py | 91 ++++++++++++++++++++------------------------ nova/db/sqlalchemy/models.py | 33 ++++++---------- 3 files changed, 73 insertions(+), 86 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 848f5febf..1e0a2a5c8 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -337,6 +337,11 @@ def key_pair_get_all_by_user(context, user_id): #################### +def network_associate(context, project_id): + """Associate a free network to a project.""" + return IMPL.network_associate(context, project_id) + + def network_count(context): """Return the number of networks.""" return IMPL.network_count(context) @@ -357,9 +362,12 @@ def network_count_reserved_ips(context, network_id): return IMPL.network_count_reserved_ips(context, network_id) -def network_create(context, values): - """Create a network from the values dictionary.""" - return IMPL.network_create(context, values) +def network_create_safe(context, values): + """Create a network from the values dict + + The network is only returned if the create succeeds. If the create violates + constraints because the network already exists, no exception is raised.""" + return IMPL.network_create_safe(context, values) def network_create_fixed_ips(context, network_id, num_vpn_clients): @@ -367,9 +375,14 @@ def network_create_fixed_ips(context, network_id, num_vpn_clients): return IMPL.network_create_fixed_ips(context, network_id, num_vpn_clients) -def network_destroy(context, network_id): - """Destroy the network or raise if it does not exist.""" - return IMPL.network_destroy(context, network_id) +def network_disassociate(context, network_id): + """Disassociate the network from project or raise if it does not exist.""" + return IMPL.network_disassociate(context, network_id) + + +def network_disassociate_all(context): + """Disassociate all networks from projects.""" + return IMPL.network_disassociate_all(context) def network_get(context, network_id): @@ -398,16 +411,6 @@ def network_get_vpn_ip(context, network_id): return IMPL.network_get_vpn_ip(context, network_id) -def network_index_count(context): - """Return count of network indexes""" - return IMPL.network_index_count(context) - - -def network_index_create(context, values): - """Create a network index from the values dict""" - return IMPL.network_index_create(context, values) - - def network_set_cidr(context, network_id, cidr): """Set the Classless Inner Domain Routing for the network""" return IMPL.network_set_cidr(context, network_id, cidr) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index b5caae940..dc7001b93 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -19,14 +19,13 @@ Implementation of SQLAlchemy backend """ -import sys - from nova import db from nova import exception from nova import flags from nova.db.sqlalchemy import models from nova.db.sqlalchemy.session import get_session from sqlalchemy import or_ +from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import joinedload_all from sqlalchemy.sql import func @@ -536,6 +535,24 @@ def key_pair_get_all_by_user(_context, user_id): ################### +def network_associate(_context, project_id): + session = get_session() + with session.begin(): + network_ref = session.query(models.Network + ).filter_by(deleted=False + ).filter_by(project_id=None + ).with_lockmode('update' + ).first() + # NOTE(vish): if with_lockmode isn't supported, as in sqlite, + # then this has concurrency issues + if not network_ref: + raise db.NoMoreNetworks() + network_ref['project_id'] = project_id + session.add(network_ref) + return network_ref + + + def network_count(_context): return models.Network.count() @@ -568,30 +585,24 @@ def network_count_reserved_ips(_context, network_id): ).count() -def network_create(_context, values): +def network_create_safe(_context, values): network_ref = models.Network() for (key, value) in values.iteritems(): network_ref[key] = value - network_ref.save() - return network_ref + try: + network_ref.save() + return network_ref + except IntegrityError: + return None + + +def network_disassociate(context, network_id): + db.network.update(context, network_id, {'project_id': None}) -def network_destroy(_context, network_id): +def network_disassociate_all(context): session = get_session() - with session.begin(): - # TODO(vish): do we have to use sql here? - session.execute('update networks set deleted=1 where id=:id', - {'id': network_id}) - session.execute('update fixed_ips set deleted=1 where network_id=:id', - {'id': network_id}) - session.execute('update floating_ips set deleted=1 ' - 'where fixed_ip_id in ' - '(select id from fixed_ips ' - 'where network_id=:id)', - {'id': network_id}) - session.execute('update network_indexes set network_id=NULL ' - 'where network_id=:id', - {'id': network_id}) + session.execute('update networks set project_id=NULL') def network_get(_context, network_id): @@ -622,33 +633,6 @@ def network_get_by_bridge(_context, bridge): return rv -def network_get_index(_context, network_id): - session = get_session() - with session.begin(): - network_index = session.query(models.NetworkIndex - ).filter_by(network_id=None - ).filter_by(deleted=False - ).with_lockmode('update' - ).first() - if not network_index: - raise db.NoMoreNetworks() - network_index['network'] = models.Network.find(network_id, - session=session) - session.add(network_index) - return network_index['index'] - - -def network_index_count(_context): - return models.NetworkIndex.count() - - -def network_index_create(_context, values): - network_index_ref = models.NetworkIndex() - for (key, value) in values.iteritems(): - network_index_ref[key] = value - network_index_ref.save() - - def network_set_host(_context, network_id, host_id): session = get_session() with session.begin(): @@ -680,14 +664,23 @@ def network_update(_context, network_id, values): ################### -def project_get_network(_context, project_id): +def project_get_network(context, project_id): session = get_session() rv = session.query(models.Network ).filter_by(project_id=project_id ).filter_by(deleted=False ).first() if not rv: - raise exception.NotFound('No network for project: %s' % project_id) + try: + return db.network_associate(context, project_id) + except IntegrityError: + # NOTE(vish): We hit this if there is a race and two + # processes are attempting to allocate the + # network at the same time + rv = session.query(models.Network + ).filter_by(project_id=project_id + ).filter_by(deleted=False + ).first() return rv diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index f6ba7953f..cfbe474c6 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -25,7 +25,7 @@ import datetime # TODO(vish): clean up these imports from sqlalchemy.orm import relationship, backref, exc, object_mapper -from sqlalchemy import Column, Integer, String +from sqlalchemy import Column, Integer, String, schema from sqlalchemy import ForeignKey, DateTime, Boolean, Text from sqlalchemy.ext.declarative import declarative_base @@ -363,10 +363,13 @@ class KeyPair(BASE, NovaBase): class Network(BASE, NovaBase): """Represents a network""" __tablename__ = 'networks' + __table_args__ = (schema.UniqueConstraint("vpn_public_address", + "vpn_public_port"), + {'mysql_engine': 'InnoDB'}) id = Column(Integer, primary_key=True) injected = Column(Boolean, default=False) - cidr = Column(String(255)) + cidr = Column(String(255), unique=True) netmask = Column(String(255)) bridge = Column(String(255)) gateway = Column(String(255)) @@ -379,27 +382,16 @@ class Network(BASE, NovaBase): vpn_private_address = Column(String(255)) dhcp_start = Column(String(255)) - project_id = Column(String(255)) + # NOTE(vish): The unique constraint below helps avoid a race condition + # when associating a network, but it also means that we + # can't associate two networks with one project. + project_id = Column(String(255), unique=True) host = Column(String(255)) # , ForeignKey('hosts.id')) -class NetworkIndex(BASE, NovaBase): - """Represents a unique offset for a network - - Currently vlan number, vpn port, and fixed ip ranges are keyed off of - this index. These may ultimately need to be converted to separate - pools. - """ - __tablename__ = 'network_indexes' - id = Column(Integer, primary_key=True) - index = Column(Integer) - network_id = Column(Integer, ForeignKey('networks.id'), nullable=True) - network = relationship(Network, backref=backref('network_index', - uselist=False)) - class AuthToken(BASE, NovaBase): - """Represents an authorization token for all API transactions. Fields - are a string representing the actual token and a user id for mapping + """Represents an authorization token for all API transactions. Fields + are a string representing the actual token and a user id for mapping to the actual user""" __tablename__ = 'auth_tokens' token_hash = Column(String(255), primary_key=True) @@ -409,7 +401,6 @@ class AuthToken(BASE, NovaBase): cdn_management_url = Column(String(255)) - # TODO(vish): can these both come from the same baseclass? class FixedIp(BASE, NovaBase): """Represents a fixed ip for an instance""" @@ -476,7 +467,7 @@ def register_models(): """Register Models and create metadata""" from sqlalchemy import create_engine models = (Service, Instance, Volume, ExportDevice, - FixedIp, FloatingIp, Network, NetworkIndex, + FixedIp, FloatingIp, Network, AuthToken) # , Image, Host) engine = create_engine(FLAGS.sql_connection, echo=False) for model in models: -- cgit From 84fbad82d65b837d43f138e7a5acd24f182499e2 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 28 Sep 2010 12:09:17 -0700 Subject: move default group creation to api --- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 6 ++++++ 2 files changed, 11 insertions(+) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 602c3cf09..5e033b59d 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -604,6 +604,11 @@ def security_group_destroy(context, security_group_id): return IMPL.security_group_destroy(context, security_group_id) +def security_group_destroy_all(context): + """Deletes a security group""" + return IMPL.security_group_destroy_all(context) + + #################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d2847506e..07ea5d145 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -947,6 +947,12 @@ def security_group_destroy(_context, security_group_id): 'where group_id=:id', {'id': security_group_id}) +def security_group_destroy_all(_context): + session = get_session() + with session.begin(): + # TODO(vish): do we have to use sql here? + session.execute('update security_group set deleted=1') + session.execute('update security_group_rules set deleted=1') ################### -- cgit From d9855ba51f53a27f5475b3c0b7f669b378ccc006 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 28 Sep 2010 20:53:24 -0700 Subject: fix eagerload to be joins that filter by deleted == False --- nova/db/sqlalchemy/api.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d2847506e..8b754c78e 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -25,7 +25,7 @@ from nova import flags from nova.db.sqlalchemy import models from nova.db.sqlalchemy.session import get_session from sqlalchemy import or_ -from sqlalchemy.orm import eagerload, joinedload_all +from sqlalchemy.orm import contains_eager, eagerload, joinedload_all from sqlalchemy.sql import func FLAGS = flags.FLAGS @@ -711,7 +711,7 @@ def auth_create_token(_context, token): tk[k] = v tk.save() return tk - + ################### @@ -868,7 +868,9 @@ def volume_update(_context, volume_id, values): def security_group_get_all(_context): session = get_session() return session.query(models.SecurityGroup - ).options(eagerload('rules') + ).join(models.SecurityGroupIngressRule + ).options(contains_eager(models.SecurityGroup.rules) + ).filter(models.SecurityGroupIngressRule.deleted == False ).filter_by(deleted=False ).all() @@ -876,7 +878,11 @@ def security_group_get_all(_context): def security_group_get(_context, security_group_id): session = get_session() result = session.query(models.SecurityGroup - ).options(eagerload('rules') + ).join(models.SecurityGroupIngressRule + ).options(contains_eager(models.SecurityGroup.rules) + ).filter(models.SecurityGroupIngressRule.deleted == False + ).filter_by(deleted=False + ).filter_by(id=security_group_id ).get(security_group_id) if not result: raise exception.NotFound("No secuity group with id %s" % @@ -887,8 +893,11 @@ def security_group_get(_context, security_group_id): def security_group_get_by_name(context, project_id, group_name): session = get_session() group_ref = session.query(models.SecurityGroup - ).options(eagerload('rules') - ).options(eagerload('instances') + ).join(models.SecurityGroupIngressRule + ).join(models.Instances + ).options(contains_eager(models.SecurityGroup.rules) + ).options(contains_eager(models.SecurityGroup.instances) + ).filter(models.SecurityGroupIngressRule.deleted == False ).filter_by(project_id=project_id ).filter_by(name=group_name ).filter_by(deleted=False @@ -903,7 +912,9 @@ def security_group_get_by_name(context, project_id, group_name): def security_group_get_by_project(_context, project_id): session = get_session() return session.query(models.SecurityGroup - ).options(eagerload('rules') + ).join(models.SecurityGroupIngressRule + ).options(contains_eager(models.SecurityGroup.rules) + ).filter(models.SecurityGroupIngressRule.deleted == False ).filter_by(project_id=project_id ).filter_by(deleted=False ).all() -- cgit From 3124cf70c6ab2bcab570f0ffbcbe31672a9556f8 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 28 Sep 2010 21:03:45 -0700 Subject: fix join and misnamed method --- nova/db/api.py | 2 +- nova/db/sqlalchemy/api.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 602c3cf09..1e2738b99 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -589,7 +589,7 @@ def security_group_get_by_instance(context, instance_id): return IMPL.security_group_get_by_instance(context, instance_id) -def securitygroup_exists(context, project_id, group_name): +def security_group_exists(context, project_id, group_name): """Indicates if a group name exists in a project""" return IMPL.security_group_exists(context, project_id, group_name) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 8b754c78e..fcdf945eb 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -868,7 +868,7 @@ def volume_update(_context, volume_id, values): def security_group_get_all(_context): session = get_session() return session.query(models.SecurityGroup - ).join(models.SecurityGroupIngressRule + ).join(models.SecurityGroup.rules ).options(contains_eager(models.SecurityGroup.rules) ).filter(models.SecurityGroupIngressRule.deleted == False ).filter_by(deleted=False @@ -878,7 +878,7 @@ def security_group_get_all(_context): def security_group_get(_context, security_group_id): session = get_session() result = session.query(models.SecurityGroup - ).join(models.SecurityGroupIngressRule + ).join(models.SecurityGroup.rules ).options(contains_eager(models.SecurityGroup.rules) ).filter(models.SecurityGroupIngressRule.deleted == False ).filter_by(deleted=False @@ -893,7 +893,7 @@ def security_group_get(_context, security_group_id): def security_group_get_by_name(context, project_id, group_name): session = get_session() group_ref = session.query(models.SecurityGroup - ).join(models.SecurityGroupIngressRule + ).join(models.SecurityGroup.rules ).join(models.Instances ).options(contains_eager(models.SecurityGroup.rules) ).options(contains_eager(models.SecurityGroup.instances) @@ -912,7 +912,7 @@ def security_group_get_by_name(context, project_id, group_name): def security_group_get_by_project(_context, project_id): session = get_session() return session.query(models.SecurityGroup - ).join(models.SecurityGroupIngressRule + ).join(models.SecurityGroup.rules ).options(contains_eager(models.SecurityGroup.rules) ).filter(models.SecurityGroupIngressRule.deleted == False ).filter_by(project_id=project_id -- cgit From 970114e1729c35ebcc05930659bb5dfaf5b59d3d Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 29 Sep 2010 00:30:35 -0700 Subject: fix loading to ignore deleted items --- nova/db/sqlalchemy/api.py | 65 ++++++++++++++++++++++++++------------------ nova/db/sqlalchemy/models.py | 21 ++++++++------ 2 files changed, 52 insertions(+), 34 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index dad544cdb..fee50ec9c 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -29,7 +29,7 @@ from nova.db.sqlalchemy import models from nova.db.sqlalchemy.session import get_session from sqlalchemy import or_ from sqlalchemy.exc import IntegrityError -from sqlalchemy.orm import contains_eager, eagerload, joinedload_all +from sqlalchemy.orm import contains_eager, joinedload_all from sqlalchemy.sql import exists, func FLAGS = flags.FLAGS @@ -410,8 +410,17 @@ def instance_destroy(_context, instance_id): def instance_get(context, instance_id): - return models.Instance().find(instance_id, deleted=_deleted(context), - options=eagerload('security_groups')) + session = get_session() + instance_ref = session.query(models.Instance + ).options(joinedload_all('fixed_ip.floating_ips') + ).options(joinedload_all('security_groups') + ).filter_by(id=instance_id + ).filter_by(deleted=_deleted(context) + ).first() + if not instance_ref: + raise exception.NotFound('Instance %s not found' % (instance_id)) + + return instance_ref def instance_get_all(context): @@ -942,25 +951,29 @@ def volume_update(_context, volume_id, values): ################### +INSTANCES_OR = or_(models.Instance.deleted == False, + models.Instance.deleted == None) + + +RULES_OR = or_(models.SecurityGroupIngressRule.deleted == False, + models.SecurityGroupIngressRule.deleted == None) + + def security_group_get_all(_context): session = get_session() return session.query(models.SecurityGroup - ).join(models.SecurityGroup.rules - ).options(contains_eager(models.SecurityGroup.rules) - ).filter(models.SecurityGroupIngressRule.deleted == False ).filter_by(deleted=False + ).options(joinedload_all('rules') ).all() def security_group_get(_context, security_group_id): session = get_session() result = session.query(models.SecurityGroup - ).join(models.SecurityGroup.rules - ).options(contains_eager(models.SecurityGroup.rules) - ).filter(models.SecurityGroupIngressRule.deleted == False ).filter_by(deleted=False ).filter_by(id=security_group_id - ).get(security_group_id) + ).options(joinedload_all('rules') + ).first() if not result: raise exception.NotFound("No secuity group with id %s" % security_group_id) @@ -969,41 +982,41 @@ def security_group_get(_context, security_group_id): def security_group_get_by_name(context, project_id, group_name): session = get_session() - group_ref = session.query(models.SecurityGroup - ).join(models.SecurityGroup.rules - ).join(models.Instances - ).options(contains_eager(models.SecurityGroup.rules) - ).options(contains_eager(models.SecurityGroup.instances) - ).filter(models.SecurityGroupIngressRule.deleted == False + result = session.query(models.SecurityGroup ).filter_by(project_id=project_id ).filter_by(name=group_name ).filter_by(deleted=False + ).options(joinedload_all('rules') + ).options(joinedload_all('instances') ).first() - if not group_ref: + if not result: raise exception.NotFound( 'No security group named %s for project: %s' \ % (group_name, project_id)) - return group_ref + return result def security_group_get_by_project(_context, project_id): session = get_session() return session.query(models.SecurityGroup - ).join(models.SecurityGroup.rules - ).options(contains_eager(models.SecurityGroup.rules) - ).filter(models.SecurityGroupIngressRule.deleted == False ).filter_by(project_id=project_id ).filter_by(deleted=False + ).options(joinedload_all('rules') + ).outerjoin(models.SecurityGroup.rules + ).options(contains_eager(models.SecurityGroup.rules) + ).filter(RULES_OR ).all() def security_group_get_by_instance(_context, instance_id): session = get_session() - with session.begin(): - return session.query(models.Instance - ).join(models.Instance.security_groups - ).filter_by(deleted=False - ).all() + return session.query(models.SecurityGroup + ).filter_by(deleted=False + ).options(joinedload_all('rules') + ).join(models.SecurityGroup.instances + ).filter_by(id=instance_id + ).filter_by(deleted=False + ).all() def security_group_exists(_context, project_id, group_name): diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index d4caf0b52..b89616ddb 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -340,12 +340,12 @@ class ExportDevice(BASE, NovaBase): uselist=False)) -security_group_instance_association = Table('security_group_instance_association', - BASE.metadata, - Column('security_group_id', Integer, - ForeignKey('security_group.id')), - Column('instance_id', Integer, - ForeignKey('instances.id'))) +class SecurityGroupInstanceAssociation(BASE, NovaBase): + __tablename__ = 'security_group_instance_association' + id = Column(Integer, primary_key=True) + security_group_id = Column(Integer, ForeignKey('security_group.id')) + instance_id = Column(Integer, ForeignKey('instances.id')) + class SecurityGroup(BASE, NovaBase): """Represents a security group""" @@ -358,7 +358,11 @@ class SecurityGroup(BASE, NovaBase): project_id = Column(String(255)) instances = relationship(Instance, - secondary=security_group_instance_association, + secondary="security_group_instance_association", + secondaryjoin="and_(SecurityGroup.id == SecurityGroupInstanceAssociation.security_group_id," + "Instance.id == SecurityGroupInstanceAssociation.instance_id," + "SecurityGroup.deleted == False," + "Instance.deleted == False)", backref='security_groups') @property @@ -378,7 +382,8 @@ class SecurityGroupIngressRule(BASE, NovaBase): parent_group_id = Column(Integer, ForeignKey('security_group.id')) parent_group = relationship("SecurityGroup", backref="rules", foreign_keys=parent_group_id, - primaryjoin=parent_group_id==SecurityGroup.id) + primaryjoin="and_(SecurityGroupIngressRule.parent_group_id == SecurityGroup.id," + "SecurityGroupIngressRule.deleted == False)") protocol = Column(String(5)) # "tcp", "udp", or "icmp" from_port = Column(Integer) -- cgit From c0abb5cd45314e072096e173830b2e3d379bf3e7 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 29 Sep 2010 00:42:18 -0700 Subject: removed a few extra items --- nova/db/sqlalchemy/api.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index e823bf15e..7ef92cad5 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -29,7 +29,7 @@ from nova.db.sqlalchemy import models from nova.db.sqlalchemy.session import get_session from sqlalchemy import or_ from sqlalchemy.exc import IntegrityError -from sqlalchemy.orm import contains_eager, joinedload_all +from sqlalchemy.orm import joinedload_all from sqlalchemy.sql import exists, func FLAGS = flags.FLAGS @@ -951,14 +951,6 @@ def volume_update(_context, volume_id, values): ################### -INSTANCES_OR = or_(models.Instance.deleted == False, - models.Instance.deleted == None) - - -RULES_OR = or_(models.SecurityGroupIngressRule.deleted == False, - models.SecurityGroupIngressRule.deleted == None) - - def security_group_get_all(_context): session = get_session() return session.query(models.SecurityGroup @@ -1002,9 +994,6 @@ def security_group_get_by_project(_context, project_id): ).filter_by(project_id=project_id ).filter_by(deleted=False ).options(joinedload_all('rules') - ).outerjoin(models.SecurityGroup.rules - ).options(contains_eager(models.SecurityGroup.rules) - ).filter(RULES_OR ).all() -- cgit From 793516d14630a82bb3592f626b753736e63955ec Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 29 Sep 2010 01:33:30 -0700 Subject: autocreate the models and use security_groups --- nova/db/sqlalchemy/api.py | 4 ++-- nova/db/sqlalchemy/models.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 7ef92cad5..200fb3b3c 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1031,7 +1031,7 @@ def security_group_destroy(_context, security_group_id): session = get_session() with session.begin(): # TODO(vish): do we have to use sql here? - session.execute('update security_group set deleted=1 where id=:id', + session.execute('update security_groups set deleted=1 where id=:id', {'id': security_group_id}) session.execute('update security_group_rules set deleted=1 ' 'where group_id=:id', @@ -1041,7 +1041,7 @@ def security_group_destroy_all(_context): session = get_session() with session.begin(): # TODO(vish): do we have to use sql here? - session.execute('update security_group set deleted=1') + session.execute('update security_groups set deleted=1') session.execute('update security_group_rules set deleted=1') ################### diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index b89616ddb..c2dbf2345 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -25,7 +25,7 @@ import datetime # TODO(vish): clean up these imports from sqlalchemy.orm import relationship, backref, exc, object_mapper -from sqlalchemy import Column, Integer, String, Table +from sqlalchemy import Column, Integer, String from sqlalchemy import ForeignKey, DateTime, Boolean, Text from sqlalchemy.ext.declarative import declarative_base @@ -343,13 +343,13 @@ class ExportDevice(BASE, NovaBase): class SecurityGroupInstanceAssociation(BASE, NovaBase): __tablename__ = 'security_group_instance_association' id = Column(Integer, primary_key=True) - security_group_id = Column(Integer, ForeignKey('security_group.id')) + security_group_id = Column(Integer, ForeignKey('security_groups.id')) instance_id = Column(Integer, ForeignKey('instances.id')) class SecurityGroup(BASE, NovaBase): """Represents a security group""" - __tablename__ = 'security_group' + __tablename__ = 'security_groups' id = Column(Integer, primary_key=True) name = Column(String(255)) @@ -379,7 +379,7 @@ class SecurityGroupIngressRule(BASE, NovaBase): __tablename__ = 'security_group_rules' id = Column(Integer, primary_key=True) - parent_group_id = Column(Integer, ForeignKey('security_group.id')) + parent_group_id = Column(Integer, ForeignKey('security_groups.id')) parent_group = relationship("SecurityGroup", backref="rules", foreign_keys=parent_group_id, primaryjoin="and_(SecurityGroupIngressRule.parent_group_id == SecurityGroup.id," @@ -392,7 +392,7 @@ class SecurityGroupIngressRule(BASE, NovaBase): # Note: This is not the parent SecurityGroup. It's SecurityGroup we're # granting access for. - group_id = Column(Integer, ForeignKey('security_group.id')) + group_id = Column(Integer, ForeignKey('security_groups.id')) class KeyPair(BASE, NovaBase): @@ -546,7 +546,7 @@ def register_models(): from sqlalchemy import create_engine models = (Service, Instance, Volume, ExportDevice, FixedIp, FloatingIp, Network, NetworkIndex, SecurityGroup, SecurityGroupIngressRule, - AuthToken) # , Image, Host + SecurityGroupInstanceAssociation, AuthToken) # , Image, Host engine = create_engine(FLAGS.sql_connection, echo=False) for model in models: model.metadata.create_all(engine) -- cgit From 5fa5a0b0b9e13f8f44b257eac0385730c959b92f Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 29 Sep 2010 01:58:19 -0700 Subject: fix the primary and secondary join --- nova/db/sqlalchemy/api.py | 4 ++-- nova/db/sqlalchemy/models.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 200fb3b3c..447d20b25 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -412,10 +412,10 @@ def instance_destroy(_context, instance_id): def instance_get(context, instance_id): session = get_session() instance_ref = session.query(models.Instance - ).options(joinedload_all('fixed_ip.floating_ips') - ).options(joinedload_all('security_groups') ).filter_by(id=instance_id ).filter_by(deleted=_deleted(context) + ).options(joinedload_all('security_groups') + ).options(joinedload_all('fixed_ip.floating_ips') ).first() if not instance_ref: raise exception.NotFound('Instance %s not found' % (instance_id)) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index c2dbf2345..67142ad78 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -359,9 +359,9 @@ class SecurityGroup(BASE, NovaBase): instances = relationship(Instance, secondary="security_group_instance_association", - secondaryjoin="and_(SecurityGroup.id == SecurityGroupInstanceAssociation.security_group_id," - "Instance.id == SecurityGroupInstanceAssociation.instance_id," - "SecurityGroup.deleted == False," + primaryjoin="and_(SecurityGroup.id == SecurityGroupInstanceAssociation.security_group_id," + "SecurityGroup.deleted == False)", + secondaryjoin="and_(SecurityGroupInstanceAssociation.instance_id == Instance.id," "Instance.deleted == False)", backref='security_groups') -- cgit From c9d2b8bcb365f326a47df93920c11be2ca054b18 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 30 Sep 2010 23:04:53 -0700 Subject: Fixed flat network manager with network index gone. Both managers use ips created through nova manage. Use of project_get_network is minimized to make way for managers that would prefer to use cluste or host based ips instead of project based ips. --- nova/db/api.py | 7 ++++++- nova/db/sqlalchemy/api.py | 14 +++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 9ba994909..1eeee524b 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -400,10 +400,15 @@ def network_get_associated_fixed_ips(context, network_id): def network_get_by_bridge(context, bridge): - """Get an network or raise if it does not exist.""" + """Get a network by bridge or raise if it does not exist.""" return IMPL.network_get_by_bridge(context, bridge) +def network_get_by_instance(context, instance_id): + """Get a network by instance id or raise if it does not exist.""" + return IMPL.network_get_by_instance(context, instance_id) + + def network_get_index(context, network_id): """Get non-conflicting index for network""" return IMPL.network_get_index(context, network_id) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 9d17ccec4..c8099c83e 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -28,7 +28,6 @@ from nova.db.sqlalchemy.session import get_session from sqlalchemy import or_ from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import joinedload_all -from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.sql import exists, func FLAGS = flags.FLAGS @@ -664,6 +663,19 @@ def network_get_by_bridge(_context, bridge): return rv +def network_get_by_instance(_context, instance_id): + session = get_session() + rv = session.query(models.Network + ).filter_by(deleted=False + ).join(models.Network.fixed_ips + ).filter_by(instance_id=instance_id + ).filter_by(deleted=False + ).first() + if not rv: + raise exception.NotFound('No network for instance %s' % instance_id) + return rv + + def network_set_host(_context, network_id, host_id): session = get_session() with session.begin(): -- cgit From a4720c03a8260fb920035d072799d3ecc478db99 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 4 Oct 2010 21:58:22 +0200 Subject: Merge security group related changes from lp:~anso/nova/deploy --- nova/db/sqlalchemy/api.py | 105 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 25 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d395b7e2c..bc5ef5a9b 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -572,11 +572,13 @@ def instance_get(context, instance_id, session=None): if is_admin_context(context): result = session.query(models.Instance + ).options(joinedload('security_groups') ).filter_by(id=instance_id ).filter_by(deleted=can_read_deleted(context) ).first() elif is_user_context(context): result = session.query(models.Instance + ).options(joinedload('security_groups') ).filter_by(project_id=context.project.id ).filter_by(id=instance_id ).filter_by(deleted=False @@ -592,6 +594,7 @@ def instance_get_all(context): session = get_session() return session.query(models.Instance ).options(joinedload_all('fixed_ip.floating_ips') + ).options(joinedload('security_groups') ).filter_by(deleted=can_read_deleted(context) ).all() @@ -601,6 +604,7 @@ def instance_get_all_by_user(context, user_id): session = get_session() return session.query(models.Instance ).options(joinedload_all('fixed_ip.floating_ips') + ).options(joinedload('security_groups') ).filter_by(deleted=can_read_deleted(context) ).filter_by(user_id=user_id ).all() @@ -613,6 +617,7 @@ def instance_get_all_by_project(context, project_id): session = get_session() return session.query(models.Instance ).options(joinedload_all('fixed_ip.floating_ips') + ).options(joinedload('security_groups') ).filter_by(project_id=project_id ).filter_by(deleted=can_read_deleted(context) ).all() @@ -625,12 +630,14 @@ def instance_get_all_by_reservation(context, reservation_id): if is_admin_context(context): return session.query(models.Instance ).options(joinedload_all('fixed_ip.floating_ips') + ).options(joinedload('security_groups') ).filter_by(reservation_id=reservation_id ).filter_by(deleted=can_read_deleted(context) ).all() elif is_user_context(context): return session.query(models.Instance ).options(joinedload_all('fixed_ip.floating_ips') + ).options(joinedload('security_groups') ).filter_by(project_id=context.project.id ).filter_by(reservation_id=reservation_id ).filter_by(deleted=False @@ -643,11 +650,13 @@ def instance_get_by_ec2_id(context, ec2_id): if is_admin_context(context): result = session.query(models.Instance + ).options(joinedload('security_groups') ).filter_by(ec2_id=ec2_id ).filter_by(deleted=can_read_deleted(context) ).first() elif is_user_context(context): result = session.query(models.Instance + ).options(joinedload('security_groups') ).filter_by(project_id=context.project.id ).filter_by(ec2_id=ec2_id ).filter_by(deleted=False @@ -721,9 +730,10 @@ def instance_add_security_group(context, instance_id, security_group_id): """Associate the given security group with the given instance""" session = get_session() with session.begin(): - instance_ref = models.Instance.find(instance_id, session=session) - security_group_ref = models.SecurityGroup.find(security_group_id, - session=session) + instance_ref = instance_get(context, instance_id, session=session) + security_group_ref = security_group_get(context, + security_group_id, + session=session) instance_ref.security_groups += [security_group_ref] instance_ref.save(session=session) @@ -1202,6 +1212,7 @@ def volume_get(context, volume_id, session=None): @require_admin_context def volume_get_all(context): + session = get_session() return session.query(models.Volume ).filter_by(deleted=can_read_deleted(context) ).all() @@ -1292,27 +1303,39 @@ def volume_update(context, volume_id, values): ################### -def security_group_get_all(_context): +@require_context +def security_group_get_all(context): session = get_session() return session.query(models.SecurityGroup - ).filter_by(deleted=False + ).filter_by(deleted=can_read_deleted(context) ).options(joinedload_all('rules') ).all() -def security_group_get(_context, security_group_id): - session = get_session() - result = session.query(models.SecurityGroup - ).filter_by(deleted=False - ).filter_by(id=security_group_id - ).options(joinedload_all('rules') - ).first() +@require_context +def security_group_get(context, security_group_id, session=None): + if not session: + session = get_session() + if is_admin_context(context): + result = session.query(models.SecurityGroup + ).filter_by(deleted=can_read_deleted(context), + ).filter_by(id=security_group_id + ).options(joinedload_all('rules') + ).first() + else: + result = session.query(models.SecurityGroup + ).filter_by(deleted=False + ).filter_by(id=security_group_id + ).filter_by(project_id=context.project_id + ).options(joinedload_all('rules') + ).first() if not result: raise exception.NotFound("No secuity group with id %s" % security_group_id) return result +@require_context def security_group_get_by_name(context, project_id, group_name): session = get_session() result = session.query(models.SecurityGroup @@ -1329,7 +1352,8 @@ def security_group_get_by_name(context, project_id, group_name): return result -def security_group_get_by_project(_context, project_id): +@require_context +def security_group_get_by_project(context, project_id): session = get_session() return session.query(models.SecurityGroup ).filter_by(project_id=project_id @@ -1338,7 +1362,8 @@ def security_group_get_by_project(_context, project_id): ).all() -def security_group_get_by_instance(_context, instance_id): +@require_context +def security_group_get_by_instance(context, instance_id): session = get_session() return session.query(models.SecurityGroup ).filter_by(deleted=False @@ -1349,15 +1374,17 @@ def security_group_get_by_instance(_context, instance_id): ).all() -def security_group_exists(_context, project_id, group_name): +@require_context +def security_group_exists(context, project_id, group_name): try: - group = security_group_get_by_name(_context, project_id, group_name) + group = security_group_get_by_name(context, project_id, group_name) return group != None except exception.NotFound: return False -def security_group_create(_context, values): +@require_context +def security_group_create(context, values): security_group_ref = models.SecurityGroup() # FIXME(devcamcar): Unless I do this, rules fails with lazy load exception # once save() is called. This will get cleaned up in next orm pass. @@ -1368,7 +1395,8 @@ def security_group_create(_context, values): return security_group_ref -def security_group_destroy(_context, security_group_id): +@require_context +def security_group_destroy(context, security_group_id): session = get_session() with session.begin(): # TODO(vish): do we have to use sql here? @@ -1378,35 +1406,62 @@ def security_group_destroy(_context, security_group_id): 'where group_id=:id', {'id': security_group_id}) -def security_group_destroy_all(_context): - session = get_session() +@require_context +def security_group_destroy_all(context, session=None): + if not session: + session = get_session() with session.begin(): # TODO(vish): do we have to use sql here? session.execute('update security_groups set deleted=1') session.execute('update security_group_rules set deleted=1') + ################### -def security_group_rule_create(_context, values): +@require_context +def security_group_rule_get(context, security_group_rule_id, session=None): + if not session: + session = get_session() + if is_admin_context(context): + result = session.query(models.SecurityGroupIngressRule + ).filter_by(deleted=can_read_deleted(context) + ).filter_by(id=security_group_rule_id + ).first() + else: + # TODO(vish): Join to group and check for project_id + result = session.query(models.SecurityGroupIngressRule + ).filter_by(deleted=False + ).filter_by(id=security_group_rule_id + ).first() + if not result: + raise exception.NotFound("No secuity group rule with id %s" % + security_group_rule_id) + return result + + +@require_context +def security_group_rule_create(context, values): security_group_rule_ref = models.SecurityGroupIngressRule() for (key, value) in values.iteritems(): security_group_rule_ref[key] = value security_group_rule_ref.save() return security_group_rule_ref -def security_group_rule_destroy(_context, security_group_rule_id): +@require_context +def security_group_rule_destroy(context, security_group_rule_id): session = get_session() with session.begin(): - model = models.SecurityGroupIngressRule - security_group_rule = model.find(security_group_rule_id, - session=session) + security_group_rule = security_group_rule_get(context, + security_group_rule_id, + session=session) security_group_rule.delete(session=session) ################### +@require_admin_context def host_get_networks(context, host): session = get_session() with session.begin(): -- cgit From ac1dfd25c4b356c1725339709e535d4147feda3c Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 12 Oct 2010 14:29:57 +0200 Subject: Remove spurious project_id addition to KeyPair model. --- nova/db/sqlalchemy/models.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 584214deb..85b7c0aae 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -351,7 +351,6 @@ class KeyPair(BASE, NovaBase): name = Column(String(255)) user_id = Column(String(255)) - project_id = Column(String(255)) fingerprint = Column(String(255)) public_key = Column(Text) -- cgit From 3894e22d517447fb3d5e9c367ffd2e67162f4b0f Mon Sep 17 00:00:00 2001 From: Michael Gundlach Date: Tue, 12 Oct 2010 13:09:35 -0400 Subject: Fix bug 659330 --- nova/db/sqlalchemy/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index ebcb73413..fc99a535d 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -169,7 +169,7 @@ class Instance(BASE, NovaBase): @property def name(self): - return self.internal_id + return "instance-%d" % self.internal_id image_id = Column(String(255)) kernel_id = Column(String(255)) -- cgit From aa92c017ab91d7fb0ec9c2cd5fd420e625ce2dbd Mon Sep 17 00:00:00 2001 From: Michael Gundlach Date: Tue, 12 Oct 2010 18:27:59 -0400 Subject: Revert 64 bit storage and use 32 bit again. I didn't notice that we verify that randomly created uids don't already exist in the DB, so the chance of collision isn't really an issue until we get to tens of thousands of machines. Even then we should only expect a few retries before finding a free ID. --- nova/db/sqlalchemy/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 9809eb7a7..fc99a535d 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -25,7 +25,7 @@ import datetime # TODO(vish): clean up these imports from sqlalchemy.orm import relationship, backref, exc, object_mapper -from sqlalchemy import Column, PickleType, Integer, String +from sqlalchemy import Column, Integer, String from sqlalchemy import ForeignKey, DateTime, Boolean, Text from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.declarative import declarative_base @@ -152,7 +152,7 @@ class Instance(BASE, NovaBase): __tablename__ = 'instances' __prefix__ = 'i' id = Column(Integer, primary_key=True) - internal_id = Column(PickleType(mutable=False), unique=True) + internal_id = Column(Integer, unique=True) admin_pass = Column(String(255)) -- cgit