Skip to content

Commit

Permalink
Add update method of security group name and description
Browse files Browse the repository at this point in the history
make it possible to edit the name and description of
common security groups, we can not rename the default.

Fixes: bug #918393

Change-Id: Id6e02cd1054452889282b3ff4fb04b2071980cc8
  • Loading branch information
niuzhenguo committed May 28, 2013
1 parent 55ccdbc commit 1ddb1bc
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 1 deletion.
26 changes: 25 additions & 1 deletion nova/api/openstack/compute/contrib/security_groups.py
Expand Up @@ -295,6 +295,30 @@ def create(self, req, body):
return {'security_group': self._format_security_group(context,
group_ref)}

@wsgi.serializers(xml=SecurityGroupTemplate)
def update(self, req, id, body):
"""Update a security group."""
context = _authorize_context(req)

id = self.security_group_api.validate_id(id)

security_group = self.security_group_api.get(context, None, id,
map_exception=True)
security_group_data = self._from_body(body, 'security_group')

group_name = security_group_data.get('name', None)
group_description = security_group_data.get('description', None)

self.security_group_api.validate_property(group_name, 'name', None)
self.security_group_api.validate_property(group_description,
'description', None)

group_ref = self.security_group_api.update_security_group(
context, security_group, group_name, group_description)

return {'security_group': self._format_security_group(context,
group_ref)}


class SecurityGroupRulesController(SecurityGroupControllerBase):

Expand Down Expand Up @@ -568,7 +592,7 @@ class Security_groups(extensions.ExtensionDescriptor):
name = "SecurityGroups"
alias = "os-security-groups"
namespace = "http://docs.openstack.org/compute/ext/securitygroups/api/v1.1"
updated = "2011-07-21T00:00:00+00:00"
updated = "2013-05-28T00:00:00+00:00"

def get_controller_extensions(self):
controller = SecurityGroupActionController()
Expand Down
15 changes: 15 additions & 0 deletions nova/compute/api.py
Expand Up @@ -2905,6 +2905,21 @@ def create_security_group(self, context, name, description):

return group_ref

def update_security_group(self, context, security_group,
name, description):
if security_group['name'] in RO_SECURITY_GROUPS:
msg = (_("Unable to update system group '%s'") %
security_group['name'])
self.raise_invalid_group(msg)

group = {'name': name,
'description': description}

group_ref = self.db.security_group_update(context,
security_group['id'],
group)
return group_ref

def get(self, context, name=None, id=None, map_exception=False):
self.ensure_default(context)
try:
Expand Down
5 changes: 5 additions & 0 deletions nova/db/api.py
Expand Up @@ -1100,6 +1100,11 @@ def security_group_create(context, values):
return IMPL.security_group_create(context, values)


def security_group_update(context, security_group_id, values):
"""Update a security group."""
return IMPL.security_group_update(context, security_group_id, values)


def security_group_ensure_default(context):
"""Ensure default security group exists for a project_id.
Expand Down
12 changes: 12 additions & 0 deletions nova/db/sqlalchemy/api.py
Expand Up @@ -3258,6 +3258,18 @@ def security_group_create(context, values, session=None):
return security_group_ref


@require_context
def security_group_update(context, security_group_id, values, session=None):
security_group_ref = model_query(context, models.SecurityGroup,
session=session).filter_by(id=security_group_id).first()

if not security_group_ref:
raise exception.SecurityGroupNotFound(
security_group_id=security_group_id)
security_group_ref.update(values)
return security_group_ref


def security_group_ensure_default(context, session=None):
"""Ensure default security group exists for a project_id."""
try:
Expand Down
18 changes: 18 additions & 0 deletions nova/network/security_group/quantum_driver.py
Expand Up @@ -60,6 +60,24 @@ def create_security_group(self, context, name, description):
raise e
return self._convert_to_nova_security_group_format(security_group)

def update_security_group(self, context, security_group,
name, description):
quantum = quantumv2.get_client(context)
body = self._make_quantum_security_group_dict(name, description)
try:
security_group = quantum.update_security_group(
security_group['id'], body).get('security_group')
except q_exc.QuantumClientException as e:
LOG.exception(_("Quantum Error updating security group %s"),
name)
if e.status_code == 401:
# TODO(arosen) Cannot raise generic response from quantum here
# as this error code could be related to bad input or over
# quota
raise exc.HTTPBadRequest()
raise e
return self._convert_to_nova_security_group_format(security_group)

def _convert_to_nova_security_group_format(self, security_group):
nova_group = {}
nova_group['id'] = security_group['id']
Expand Down
4 changes: 4 additions & 0 deletions nova/network/security_group/security_group_base.py
Expand Up @@ -185,6 +185,10 @@ def populate_security_groups(self, instance, security_groups):
def create_security_group(self, context, name, description):
raise NotImplementedError()

def update_security_group(self, context, security_group,
name, description):
raise NotImplementedError()

def get(self, context, name=None, id=None, map_exception=False):
raise NotImplementedError()

Expand Down
Expand Up @@ -116,6 +116,10 @@ def test_create_security_group_quota_limit(self):
# Enforced by Quantum server.
pass

def test_update_security_group(self):
# Enforced by Quantum server.
pass

def test_get_security_group_list(self):
self._create_sg_template().get('security_group')
req = fakes.HTTPRequest.blank('/v2/fake/os-security-groups')
Expand Down
48 changes: 48 additions & 0 deletions nova/tests/api/openstack/compute/contrib/test_security_groups.py
Expand Up @@ -408,6 +408,54 @@ def test_get_security_group_by_non_existing_id(self):
self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete,
req, self.fake_id)

def test_update_security_group(self):
sg = security_group_template(id=2, rules=[])
sg_update = security_group_template(id=2, rules=[],
name='update_name', description='update_desc')

def return_security_group(context, group_id):
self.assertEquals(sg['id'], group_id)
return security_group_db(sg)

def return_update_security_group(context, group_id, values):
self.assertEquals(sg_update['id'], group_id)
self.assertEquals(sg_update['name'], values['name'])
self.assertEquals(sg_update['description'], values['description'])
return security_group_db(sg_update)

self.stubs.Set(nova.db, 'security_group_update',
return_update_security_group)
self.stubs.Set(nova.db, 'security_group_get',
return_security_group)

req = fakes.HTTPRequest.blank('/v2/fake/os-security-groups/2')
res_dict = self.controller.update(req, '2',
{'security_group': sg_update})

expected = {'security_group': sg_update}
self.assertEquals(res_dict, expected)

def test_update_security_group_name_to_default(self):
sg = security_group_template(id=2, rules=[], name='default')

def return_security_group(context, group_id):
self.assertEquals(sg['id'], group_id)
return security_group_db(sg)

self.stubs.Set(nova.db, 'security_group_get',
return_security_group)

req = fakes.HTTPRequest.blank('/v2/fake/os-security-groups/2')
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
req, '2', {'security_group': sg})

def test_update_default_security_group_fail(self):
sg = security_group_template()

req = fakes.HTTPRequest.blank('/v2/fake/os-security-groups/1')
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
req, '1', {'security_group': sg})

def test_delete_security_group_by_id(self):
sg = security_group_template(id=1, rules=[])

Expand Down
13 changes: 13 additions & 0 deletions nova/tests/test_db_api.py
Expand Up @@ -1110,6 +1110,19 @@ def test_get_snap_mapping_non_admin(self):
ec2_id = db.get_ec2_snapshot_id_by_uuid(self.context, 'fake-uuid')
self.assertEqual(ref['id'], ec2_id)

def test_security_group_update(self):
ctxt = context.get_admin_context()
values = {'security_group': {'tenant_id': '123',
'name': 'test', 'description': 'test-description'}}
sg = db.security_group_create(ctxt, values)

values['security_group']['name'] = 'test_name'
values['security_group']['description'] = 'test_desc'
sg = db.security_group_update(ctxt, sg['id'], values)
self.assertNotEqual(None, sg)
self.assertEqual(sg['security_group']['name'], 'test_name')
self.assertEqual(sg['security_group']['description'], 'test_desc')

def test_bw_usage_calls(self):
ctxt = context.get_admin_context()
now = timeutils.utcnow()
Expand Down

0 comments on commit 1ddb1bc

Please sign in to comment.