summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/api/ec2/cloud.py13
-rw-r--r--nova/api/openstack/contrib/createserverext.py26
-rw-r--r--nova/api/openstack/servers.py18
-rw-r--r--nova/tests/api/openstack/contrib/test_createserverext.py97
-rw-r--r--nova/utils.py9
5 files changed, 131 insertions, 32 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index fe44191c8..049ca6f93 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -1020,14 +1020,6 @@ class CloudController(object):
'status': volume['attach_status'],
'volumeId': ec2utils.id_to_ec2_vol_id(volume_id)}
- @staticmethod
- def _convert_to_set(lst, label):
- if lst is None or lst == []:
- return None
- if not isinstance(lst, list):
- lst = [lst]
- return [{label: x} for x in lst]
-
def _format_kernel_id(self, instance_ref, result, key):
kernel_id = instance_ref['kernel_id']
if kernel_id is None:
@@ -1186,7 +1178,7 @@ class CloudController(object):
if instance.get('security_groups'):
for security_group in instance['security_groups']:
security_group_names.append(security_group['name'])
- result['groupSet'] = CloudController._convert_to_set(
+ result['groupSet'] = utils.convert_to_list_dict(
security_group_names, 'groupId')
def _format_instances(self, context, instance_id=None, use_v6=False,
@@ -1250,7 +1242,8 @@ class CloudController(object):
i['keyName'] = '%s (%s, %s)' % (i['keyName'],
instance['project_id'],
instance['host'])
- i['productCodesSet'] = self._convert_to_set([], 'product_codes')
+ i['productCodesSet'] = utils.convert_to_list_dict([],
+ 'product_codes')
self._format_instance_type(instance, i)
i['launchTime'] = instance['created_at']
i['amiLaunchIndex'] = instance['launch_index']
diff --git a/nova/api/openstack/contrib/createserverext.py b/nova/api/openstack/contrib/createserverext.py
index ba72fdb0b..af7f37f13 100644
--- a/nova/api/openstack/contrib/createserverext.py
+++ b/nova/api/openstack/contrib/createserverext.py
@@ -14,18 +14,34 @@
# License for the specific language governing permissions and limitations
# under the License
+from nova import utils
from nova.api.openstack import create_instance_helper as helper
from nova.api.openstack import extensions
from nova.api.openstack import servers
from nova.api.openstack import wsgi
-class Createserverext(extensions.ExtensionDescriptor):
- """The servers create ext
+class CreateServerController(servers.ControllerV11):
+ def _build_view(self, req, instance, is_detail=False):
+ server = super(CreateServerController, self)._build_view(req,
+ instance,
+ is_detail)
+ if is_detail:
+ self._build_security_groups(server['server'], instance)
+ return server
+
+ def _build_security_groups(self, response, inst):
+ sg_names = []
+ sec_groups = inst.get('security_groups')
+ if sec_groups:
+ sg_names = [sec_group['name'] for sec_group in sec_groups]
- Exposes addFixedIp and removeFixedIp actions on servers.
+ response['security_groups'] = utils.convert_to_list_dict(sg_names,
+ 'name')
- """
+
+class Createserverext(extensions.ExtensionDescriptor):
+ """The servers create ext"""
def get_name(self):
return "Createserverext"
@@ -58,7 +74,7 @@ class Createserverext(extensions.ExtensionDescriptor):
deserializer = wsgi.RequestDeserializer(body_deserializers)
res = extensions.ResourceExtension('os-create-server-ext',
- controller=servers.ControllerV11(),
+ controller=CreateServerController(),
deserializer=deserializer,
serializer=serializer)
resources.append(res)
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 977958f5d..acd2209af 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -928,6 +928,11 @@ class ServerXMLSerializer(wsgi.XMLDictSerializer):
server['addresses'])
server_node.appendChild(addresses_node)
+ if 'security_groups' in server:
+ security_groups_node = self._create_security_groups_node(xml_doc,
+ server['security_groups'])
+ server_node.appendChild(security_groups_node)
+
return server_node
def _server_list_to_xml(self, xml_doc, servers, detailed):
@@ -980,6 +985,19 @@ class ServerXMLSerializer(wsgi.XMLDictSerializer):
server_dict['server'])
return self.to_xml_string(node, True)
+ def _security_group_to_xml(self, doc, security_group):
+ node = doc.createElement('security_group')
+ node.setAttribute('name', str(security_group.get('name')))
+ return node
+
+ def _create_security_groups_node(self, xml_doc, security_groups):
+ security_groups_node = xml_doc.createElement('security_groups')
+ if security_groups:
+ for security_group in security_groups:
+ node = self._security_group_to_xml(xml_doc, security_group)
+ security_groups_node.appendChild(node)
+ return security_groups_node
+
def create_resource(version='1.0'):
controller = {
diff --git a/nova/tests/api/openstack/contrib/test_createserverext.py b/nova/tests/api/openstack/contrib/test_createserverext.py
index 089c8e59d..ba8fb925e 100644
--- a/nova/tests/api/openstack/contrib/test_createserverext.py
+++ b/nova/tests/api/openstack/contrib/test_createserverext.py
@@ -16,6 +16,7 @@
# under the License.
import base64
+import datetime
import json
import unittest
from xml.dom import minidom
@@ -27,15 +28,7 @@ from nova import db
from nova import exception
from nova import flags
from nova import test
-from nova import utils
import nova.api.openstack
-from nova.api.openstack import servers
-from nova.api.openstack.contrib import createserverext
-import nova.compute.api
-
-import nova.scheduler.api
-import nova.image.fake
-import nova.rpc
from nova.tests.api.openstack import fakes
@@ -52,22 +45,45 @@ DUPLICATE_NETWORKS = [('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', '10.0.1.12'),
INVALID_NETWORKS = [('invalid', 'invalid-ip-address')]
+INSTANCE = {
+ "id": 1,
+ "display_name": "test_server",
+ "uuid": FAKE_UUID,
+ "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0),
+ "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0),
+ "security_groups": [{"id": 1, "name": "test"}]
+ }
+
+
+def return_server_by_id(context, id, session=None):
+ INSTANCE['id'] = id
+ return INSTANCE
+
+
+def return_security_group_non_existing(context, project_id, group_name):
+ raise exception.SecurityGroupNotFoundForProject(project_id=project_id,
+ security_group_id=group_name)
+
+
+def return_security_group_get_by_name(context, project_id, group_name):
+ return {'id': 1, 'name': group_name}
+
+
+def return_security_group_get(context, security_group_id, session):
+ return {'id': security_group_id}
+
+
+def return_instance_add_security_group(context, instance_id,
+ security_group_id):
+ pass
+
class CreateserverextTest(test.TestCase):
def setUp(self):
super(CreateserverextTest, self).setUp()
- self.stubs = stubout.StubOutForTesting()
- fakes.FakeAuthManager.auth_data = {}
- fakes.FakeAuthDatabase.data = {}
- fakes.stub_out_auth(self.stubs)
- fakes.stub_out_image_service(self.stubs)
- fakes.stub_out_key_pair_funcs(self.stubs)
- self.allow_admin = FLAGS.allow_admin_api
def tearDown(self):
- self.stubs.UnsetAll()
- FLAGS.allow_admin_api = self.allow_admin
super(CreateserverextTest, self).tearDown()
def _setup_mock_compute_api(self):
@@ -114,6 +130,18 @@ class CreateserverextTest(test.TestCase):
'_get_kernel_ramdisk_from_image', make_stub_method((1, 1)))
return compute_api
+ def _create_security_group_request_dict(self, security_groups):
+ server = {}
+ server['name'] = 'new-server-test'
+ server['imageRef'] = 1
+ server['flavorRef'] = 1
+ if security_groups is not None:
+ sg_list = []
+ for name in security_groups:
+ sg_list.append({'name': name})
+ server['security_groups'] = sg_list
+ return {'server': server}
+
def _create_networks_request_dict(self, networks):
server = {}
server['name'] = 'new-server-test'
@@ -348,3 +376,38 @@ class CreateserverextTest(test.TestCase):
self._create_instance_with_user_data_json(user_data_contents)
self.assertEquals(response.status_int, 400)
self.assertEquals(user_data, None)
+
+ def test_create_instance_with_security_group_json(self):
+ security_groups = ['test', 'test1']
+ self.stubs.Set(nova.db.api, 'security_group_get_by_name',
+ return_security_group_get_by_name)
+ self.stubs.Set(nova.db.api, 'instance_add_security_group',
+ return_instance_add_security_group)
+ body_dict = self._create_security_group_request_dict(security_groups)
+ request = self._get_create_request_json(body_dict)
+ response = request.get_response(fakes.wsgi_app())
+ self.assertEquals(response.status_int, 202)
+
+ def test_get_server_by_id_verify_security_groups_json(self):
+ self.stubs.Set(nova.db.api, 'instance_get', return_server_by_id)
+ req = webob.Request.blank('/v1.1/123/os-create-server-ext/1')
+ req.headers['Content-Type'] = 'application/json'
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEquals(response.status_int, 200)
+ res_dict = json.loads(response.body)
+ expected_security_group = [{"name": "test"}]
+ self.assertEquals(res_dict['server']['security_groups'],
+ expected_security_group)
+
+ def test_get_server_by_id_verify_security_groups_xml(self):
+ self.stubs.Set(nova.db.api, 'instance_get', return_server_by_id)
+ req = webob.Request.blank('/v1.1/123/os-create-server-ext/1')
+ req.headers['Accept'] = 'application/xml'
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEquals(response.status_int, 200)
+ dom = minidom.parseString(response.body)
+ server = dom.childNodes[0]
+ sec_groups = server.getElementsByTagName('security_groups')[0]
+ sec_group = sec_groups.getElementsByTagName('security_group')[0]
+ self.assertEqual(INSTANCE['security_groups'][0]['name'],
+ sec_group.getAttribute("name"))
diff --git a/nova/utils.py b/nova/utils.py
index 21e6221b2..81157a4cd 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -901,3 +901,12 @@ def monkey_patch():
func = import_class("%s.%s" % (module, key))
setattr(sys.modules[module], key,\
decorator("%s.%s" % (module, key), func))
+
+
+def convert_to_list_dict(lst, label):
+ """Convert a value or list into a list of dicts"""
+ if not lst:
+ return None
+ if not isinstance(lst, list):
+ lst = [lst]
+ return [{label: x} for x in lst]