summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/auth/manager.py6
-rw-r--r--nova/db/api.py22
-rw-r--r--nova/db/sqlalchemy/api.py38
-rw-r--r--nova/db/sqlalchemy/models.py54
-rw-r--r--nova/endpoint/cloud.py14
-rw-r--r--nova/tests/api_unittest.py34
6 files changed, 160 insertions, 8 deletions
diff --git a/nova/auth/manager.py b/nova/auth/manager.py
index d5fbec7c5..6aa5721c8 100644
--- a/nova/auth/manager.py
+++ b/nova/auth/manager.py
@@ -640,11 +640,17 @@ class AuthManager(object):
with self.driver() as drv:
user_dict = drv.create_user(name, access, secret, admin)
if user_dict:
+ db.security_group_create(context={},
+ values={ 'name' : 'default',
+ 'description' : 'default',
+ 'user_id' : name })
return User(**user_dict)
def delete_user(self, user):
"""Deletes a user"""
with self.driver() as drv:
+ for security_group in db.security_group_get_by_user(context = {}, user_id=user.id):
+ db.security_group_destroy({}, security_group.id)
drv.delete_user(User.safe_id(user))
def generate_key_pair(self, user, key_name):
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'
diff --git a/nova/endpoint/cloud.py b/nova/endpoint/cloud.py
index 44997be59..7df8bd081 100644
--- a/nova/endpoint/cloud.py
+++ b/nova/endpoint/cloud.py
@@ -212,10 +212,12 @@ class CloudController(object):
return True
@rbac.allow('all')
- def describe_security_groups(self, context, group_names, **kwargs):
- groups = {'securityGroupSet': []}
+ def describe_security_groups(self, context, **kwargs):
+ groups = {'securityGroupSet':
+ [{ 'groupDescription': group.description,
+ 'groupName' : group.name,
+ 'ownerId': context.user.id } for group in db.security_group_get_by_user(context, context.user.id) ] }
- # Stubbed for now to unblock other things.
return groups
@rbac.allow('netadmin')
@@ -223,7 +225,11 @@ class CloudController(object):
return True
@rbac.allow('netadmin')
- def create_security_group(self, context, group_name, **kwargs):
+ def create_security_group(self, context, group_name, group_description):
+ db.security_group_create(context,
+ values = { 'user_id' : context.user.id,
+ 'name': group_name,
+ 'description': group_description })
return True
@rbac.allow('netadmin')
diff --git a/nova/tests/api_unittest.py b/nova/tests/api_unittest.py
index 462d1b295..87d99607d 100644
--- a/nova/tests/api_unittest.py
+++ b/nova/tests/api_unittest.py
@@ -185,6 +185,9 @@ class ApiEc2TestCase(test.BaseTestCase):
self.host = '127.0.0.1'
self.app = api.APIServerApplication({'Cloud': self.cloud})
+
+ def expect_http(self, host=None, is_secure=False):
+ """Returns a new EC2 connection"""
self.ec2 = boto.connect_ec2(
aws_access_key_id='fake',
aws_secret_access_key='fake',
@@ -194,9 +197,6 @@ class ApiEc2TestCase(test.BaseTestCase):
path='/services/Cloud')
self.mox.StubOutWithMock(self.ec2, 'new_http_connection')
-
- def expect_http(self, host=None, is_secure=False):
- """Returns a new EC2 connection"""
http = FakeHttplibConnection(
self.app, '%s:%d' % (self.host, FLAGS.cc_port), False)
# pylint: disable-msg=E1103
@@ -231,3 +231,31 @@ class ApiEc2TestCase(test.BaseTestCase):
self.assertEquals(len(results), 1)
self.manager.delete_project(project)
self.manager.delete_user(user)
+
+ def test_get_all_security_groups(self):
+ """Test that operations on security groups stick"""
+ self.expect_http()
+ self.mox.ReplayAll()
+ security_group_name = "".join(random.choice("sdiuisudfsdcnpaqwertasd") \
+ for x in range(random.randint(4, 8)))
+ user = self.manager.create_user('fake', 'fake', 'fake', admin=True)
+ project = self.manager.create_project('fake', 'fake', 'fake')
+
+ rv = self.ec2.get_all_security_groups()
+ self.assertEquals(len(rv), 1)
+ self.assertEquals(rv[0].name, 'default')
+
+ self.expect_http()
+ self.mox.ReplayAll()
+
+ self.ec2.create_security_group(security_group_name, 'test group')
+
+ self.expect_http()
+ self.mox.ReplayAll()
+
+ rv = self.ec2.get_all_security_groups()
+ self.assertEquals(len(rv), 2)
+ self.assertTrue(security_group_name in [group.name for group in rv])
+
+ self.manager.delete_project(project)
+ self.manager.delete_user(user)