Merged trunk.
This commit is contained in:
@@ -166,7 +166,7 @@ class VpnCommands(object):
|
|||||||
print address,
|
print address,
|
||||||
print vpn['host'],
|
print vpn['host'],
|
||||||
print ec2utils.id_to_ec2_id(vpn['id']),
|
print ec2utils.id_to_ec2_id(vpn['id']),
|
||||||
print vpn['state_description'],
|
print vpn['vm_state'],
|
||||||
print state
|
print state
|
||||||
else:
|
else:
|
||||||
print None
|
print None
|
||||||
@@ -869,7 +869,7 @@ class VmCommands(object):
|
|||||||
instance['hostname'],
|
instance['hostname'],
|
||||||
instance['host'],
|
instance['host'],
|
||||||
instance['instance_type'].name,
|
instance['instance_type'].name,
|
||||||
instance['state_description'],
|
instance['vm_state'],
|
||||||
instance['launched_at'],
|
instance['launched_at'],
|
||||||
instance['image_ref'],
|
instance['image_ref'],
|
||||||
instance['kernel_id'],
|
instance['kernel_id'],
|
||||||
@@ -1223,7 +1223,7 @@ class VsaCommands(object):
|
|||||||
type=vc['instance_type']['name'],
|
type=vc['instance_type']['name'],
|
||||||
fl_ip=floating_addr,
|
fl_ip=floating_addr,
|
||||||
fx_ip=fixed_addr,
|
fx_ip=fixed_addr,
|
||||||
stat=vc['state_description'],
|
stat=vc['vm_state'],
|
||||||
host=vc['host'],
|
host=vc['host'],
|
||||||
time=str(vc['created_at']))
|
time=str(vc['created_at']))
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ Admin API controller, exposed through http via the api worker.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import datetime
|
|
||||||
import netaddr
|
import netaddr
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
@@ -33,6 +32,7 @@ from nova import log as logging
|
|||||||
from nova import utils
|
from nova import utils
|
||||||
from nova.api.ec2 import ec2utils
|
from nova.api.ec2 import ec2utils
|
||||||
from nova.auth import manager
|
from nova.auth import manager
|
||||||
|
from nova.compute import vm_states
|
||||||
|
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
@@ -273,8 +273,7 @@ class AdminController(object):
|
|||||||
"""Get the VPN instance for a project ID."""
|
"""Get the VPN instance for a project ID."""
|
||||||
for instance in db.instance_get_all_by_project(context, project_id):
|
for instance in db.instance_get_all_by_project(context, project_id):
|
||||||
if (instance['image_id'] == str(FLAGS.vpn_image_id)
|
if (instance['image_id'] == str(FLAGS.vpn_image_id)
|
||||||
and not instance['state_description'] in
|
and not instance['vm_state'] in [vm_states.DELETED]):
|
||||||
['shutting_down', 'shutdown']):
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def start_vpn(self, context, project):
|
def start_vpn(self, context, project):
|
||||||
|
|||||||
@@ -1020,14 +1020,6 @@ class CloudController(object):
|
|||||||
'status': volume['attach_status'],
|
'status': volume['attach_status'],
|
||||||
'volumeId': ec2utils.id_to_ec2_vol_id(volume_id)}
|
'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):
|
def _format_kernel_id(self, instance_ref, result, key):
|
||||||
kernel_id = instance_ref['kernel_id']
|
kernel_id = instance_ref['kernel_id']
|
||||||
if kernel_id is None:
|
if kernel_id is None:
|
||||||
@@ -1186,7 +1178,7 @@ class CloudController(object):
|
|||||||
if instance.get('security_groups'):
|
if instance.get('security_groups'):
|
||||||
for security_group in instance['security_groups']:
|
for security_group in instance['security_groups']:
|
||||||
security_group_names.append(security_group['name'])
|
security_group_names.append(security_group['name'])
|
||||||
result['groupSet'] = CloudController._convert_to_set(
|
result['groupSet'] = utils.convert_to_list_dict(
|
||||||
security_group_names, 'groupId')
|
security_group_names, 'groupId')
|
||||||
|
|
||||||
def _format_instances(self, context, instance_id=None, use_v6=False,
|
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'],
|
i['keyName'] = '%s (%s, %s)' % (i['keyName'],
|
||||||
instance['project_id'],
|
instance['project_id'],
|
||||||
instance['host'])
|
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)
|
self._format_instance_type(instance, i)
|
||||||
i['launchTime'] = instance['created_at']
|
i['launchTime'] = instance['created_at']
|
||||||
i['amiLaunchIndex'] = instance['launch_index']
|
i['amiLaunchIndex'] = instance['launch_index']
|
||||||
|
|||||||
@@ -14,18 +14,34 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License
|
# under the License
|
||||||
|
|
||||||
|
from nova import utils
|
||||||
from nova.api.openstack import create_instance_helper as helper
|
from nova.api.openstack import create_instance_helper as helper
|
||||||
from nova.api.openstack import extensions
|
from nova.api.openstack import extensions
|
||||||
from nova.api.openstack import servers
|
from nova.api.openstack import servers
|
||||||
from nova.api.openstack import wsgi
|
from nova.api.openstack import wsgi
|
||||||
|
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
|
response['security_groups'] = utils.convert_to_list_dict(sg_names,
|
||||||
|
'name')
|
||||||
|
|
||||||
|
|
||||||
class Createserverext(extensions.ExtensionDescriptor):
|
class Createserverext(extensions.ExtensionDescriptor):
|
||||||
"""The servers create ext
|
"""The servers create ext"""
|
||||||
|
|
||||||
Exposes addFixedIp and removeFixedIp actions on servers.
|
|
||||||
|
|
||||||
"""
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
return "Createserverext"
|
return "Createserverext"
|
||||||
|
|
||||||
@@ -58,7 +74,7 @@ class Createserverext(extensions.ExtensionDescriptor):
|
|||||||
deserializer = wsgi.RequestDeserializer(body_deserializers)
|
deserializer = wsgi.RequestDeserializer(body_deserializers)
|
||||||
|
|
||||||
res = extensions.ResourceExtension('os-create-server-ext',
|
res = extensions.ResourceExtension('os-create-server-ext',
|
||||||
controller=servers.ControllerV11(),
|
controller=CreateServerController(),
|
||||||
deserializer=deserializer,
|
deserializer=deserializer,
|
||||||
serializer=serializer)
|
serializer=serializer)
|
||||||
resources.append(res)
|
resources.append(res)
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ class SimpleTenantUsageController(object):
|
|||||||
if info['ended_at']:
|
if info['ended_at']:
|
||||||
info['state'] = 'terminated'
|
info['state'] = 'terminated'
|
||||||
else:
|
else:
|
||||||
info['state'] = instance['state_description']
|
info['state'] = instance['vm_state']
|
||||||
|
|
||||||
now = datetime.utcnow()
|
now = datetime.utcnow()
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class CreateInstanceHelper(object):
|
|||||||
try:
|
try:
|
||||||
image_service, image_id = nova.image.get_image_service(image_href)
|
image_service, image_id = nova.image.get_image_service(image_href)
|
||||||
kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image(
|
kernel_id, ramdisk_id = self._get_kernel_ramdisk_from_image(
|
||||||
req, image_id)
|
req, image_service, image_id)
|
||||||
images = set([str(x['id']) for x in image_service.index(context)])
|
images = set([str(x['id']) for x in image_service.index(context)])
|
||||||
assert str(image_id) in images
|
assert str(image_id) in images
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
@@ -247,12 +247,12 @@ class CreateInstanceHelper(object):
|
|||||||
msg = _("Server name is an empty string")
|
msg = _("Server name is an empty string")
|
||||||
raise exc.HTTPBadRequest(explanation=msg)
|
raise exc.HTTPBadRequest(explanation=msg)
|
||||||
|
|
||||||
def _get_kernel_ramdisk_from_image(self, req, image_id):
|
def _get_kernel_ramdisk_from_image(self, req, image_service, image_id):
|
||||||
"""Fetch an image from the ImageService, then if present, return the
|
"""Fetch an image from the ImageService, then if present, return the
|
||||||
associated kernel and ramdisk image IDs.
|
associated kernel and ramdisk image IDs.
|
||||||
"""
|
"""
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
image_meta = self._image_service.show(context, image_id)
|
image_meta = image_service.show(context, image_id)
|
||||||
# NOTE(sirp): extracted to a separate method to aid unit-testing, the
|
# NOTE(sirp): extracted to a separate method to aid unit-testing, the
|
||||||
# new method doesn't need a request obj or an ImageService stub
|
# new method doesn't need a request obj or an ImageService stub
|
||||||
kernel_id, ramdisk_id = self._do_get_kernel_ramdisk_from_image(
|
kernel_id, ramdisk_id = self._do_get_kernel_ramdisk_from_image(
|
||||||
|
|||||||
@@ -928,6 +928,11 @@ class ServerXMLSerializer(wsgi.XMLDictSerializer):
|
|||||||
server['addresses'])
|
server['addresses'])
|
||||||
server_node.appendChild(addresses_node)
|
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
|
return server_node
|
||||||
|
|
||||||
def _server_list_to_xml(self, xml_doc, servers, detailed):
|
def _server_list_to_xml(self, xml_doc, servers, detailed):
|
||||||
@@ -980,6 +985,19 @@ class ServerXMLSerializer(wsgi.XMLDictSerializer):
|
|||||||
server_dict['server'])
|
server_dict['server'])
|
||||||
return self.to_xml_string(node, True)
|
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'):
|
def create_resource(version='1.0'):
|
||||||
controller = {
|
controller = {
|
||||||
|
|||||||
@@ -383,10 +383,6 @@ class API(base.Base):
|
|||||||
If you are changing this method, be sure to update both
|
If you are changing this method, be sure to update both
|
||||||
call paths.
|
call paths.
|
||||||
"""
|
"""
|
||||||
instance = dict(launch_index=num, **base_options)
|
|
||||||
instance = self.db.instance_create(context, instance)
|
|
||||||
instance_id = instance['id']
|
|
||||||
|
|
||||||
elevated = context.elevated()
|
elevated = context.elevated()
|
||||||
if security_group is None:
|
if security_group is None:
|
||||||
security_group = ['default']
|
security_group = ['default']
|
||||||
@@ -400,6 +396,10 @@ class API(base.Base):
|
|||||||
security_group_name)
|
security_group_name)
|
||||||
security_groups.append(group['id'])
|
security_groups.append(group['id'])
|
||||||
|
|
||||||
|
instance = dict(launch_index=num, **base_options)
|
||||||
|
instance = self.db.instance_create(context, instance)
|
||||||
|
instance_id = instance['id']
|
||||||
|
|
||||||
for security_group_id in security_groups:
|
for security_group_id in security_groups:
|
||||||
self.db.instance_add_security_group(elevated,
|
self.db.instance_add_security_group(elevated,
|
||||||
instance_id,
|
instance_id,
|
||||||
|
|||||||
@@ -280,6 +280,20 @@ class GlanceImageService(service.BaseImageService):
|
|||||||
image_meta = _convert_from_string(image_meta)
|
image_meta = _convert_from_string(image_meta)
|
||||||
return image_meta
|
return image_meta
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _is_image_available(context, image_meta):
|
||||||
|
"""Check image availability.
|
||||||
|
|
||||||
|
Under Glance, images are always available if the context has
|
||||||
|
an auth_token. Otherwise, we fall back to the superclass
|
||||||
|
method.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if hasattr(context, 'auth_token') and context.auth_token:
|
||||||
|
return True
|
||||||
|
return service.BaseImageService._is_image_available(context,
|
||||||
|
image_meta)
|
||||||
|
|
||||||
|
|
||||||
# utility functions
|
# utility functions
|
||||||
def _convert_timestamps_to_datetimes(image_meta):
|
def _convert_timestamps_to_datetimes(image_meta):
|
||||||
|
|||||||
@@ -32,6 +32,12 @@ from nova import exception
|
|||||||
from nova import flags
|
from nova import flags
|
||||||
import nova.scheduler
|
import nova.scheduler
|
||||||
|
|
||||||
|
# NOTE(Vek): Even though we don't use filters in here anywhere, we
|
||||||
|
# depend on default_host_filter being available in FLAGS,
|
||||||
|
# and that happens only when filters/abstract_filter.py is
|
||||||
|
# imported.
|
||||||
|
from nova.scheduler import filters
|
||||||
|
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
|
|
||||||
|
|||||||
@@ -93,12 +93,14 @@ class SchedulerManager(manager.Manager):
|
|||||||
driver_method = 'schedule_%s' % method
|
driver_method = 'schedule_%s' % method
|
||||||
elevated = context.elevated()
|
elevated = context.elevated()
|
||||||
try:
|
try:
|
||||||
host = getattr(self.driver, driver_method)(elevated, *args,
|
real_meth = getattr(self.driver, driver_method)
|
||||||
**kwargs)
|
args = (elevated,) + args
|
||||||
except AttributeError, e:
|
except AttributeError, e:
|
||||||
LOG.warning(_("Driver Method %(driver_method)s missing: %(e)s."
|
LOG.warning(_("Driver Method %(driver_method)s missing: %(e)s."
|
||||||
"Reverting to schedule()") % locals())
|
"Reverting to schedule()") % locals())
|
||||||
host = self.driver.schedule(elevated, topic, *args, **kwargs)
|
real_meth = self.driver.schedule
|
||||||
|
args = (elevated, topic) + args
|
||||||
|
host = real_meth(*args, **kwargs)
|
||||||
|
|
||||||
if not host:
|
if not host:
|
||||||
LOG.debug(_("%(topic)s %(method)s handled in Scheduler")
|
LOG.debug(_("%(topic)s %(method)s handled in Scheduler")
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
|
import datetime
|
||||||
import json
|
import json
|
||||||
import unittest
|
import unittest
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
@@ -27,15 +28,7 @@ from nova import db
|
|||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import flags
|
from nova import flags
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova import utils
|
|
||||||
import nova.api.openstack
|
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
|
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')]
|
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):
|
class CreateserverextTest(test.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(CreateserverextTest, self).setUp()
|
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):
|
def tearDown(self):
|
||||||
self.stubs.UnsetAll()
|
|
||||||
FLAGS.allow_admin_api = self.allow_admin
|
|
||||||
super(CreateserverextTest, self).tearDown()
|
super(CreateserverextTest, self).tearDown()
|
||||||
|
|
||||||
def _setup_mock_compute_api(self):
|
def _setup_mock_compute_api(self):
|
||||||
@@ -114,6 +130,18 @@ class CreateserverextTest(test.TestCase):
|
|||||||
'_get_kernel_ramdisk_from_image', make_stub_method((1, 1)))
|
'_get_kernel_ramdisk_from_image', make_stub_method((1, 1)))
|
||||||
return compute_api
|
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):
|
def _create_networks_request_dict(self, networks):
|
||||||
server = {}
|
server = {}
|
||||||
server['name'] = 'new-server-test'
|
server['name'] = 'new-server-test'
|
||||||
@@ -348,3 +376,38 @@ class CreateserverextTest(test.TestCase):
|
|||||||
self._create_instance_with_user_data_json(user_data_contents)
|
self._create_instance_with_user_data_json(user_data_contents)
|
||||||
self.assertEquals(response.status_int, 400)
|
self.assertEquals(response.status_int, 400)
|
||||||
self.assertEquals(user_data, None)
|
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"))
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import datetime
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from nova import context
|
from nova import context
|
||||||
|
from nova import exception
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova.image import glance
|
from nova.image import glance
|
||||||
|
|
||||||
@@ -105,6 +106,31 @@ class TestGlanceImageServiceProperties(BaseGlanceTest):
|
|||||||
'properties': {'prop1': 'propvalue1', 'foo': 'bar'}}
|
'properties': {'prop1': 'propvalue1', 'foo': 'bar'}}
|
||||||
self.assertEqual(image_meta, expected)
|
self.assertEqual(image_meta, expected)
|
||||||
|
|
||||||
|
def test_show_raises_when_no_authtoken_in_the_context(self):
|
||||||
|
fixtures = {'image1': {'name': 'image1', 'is_public': False,
|
||||||
|
'foo': 'bar',
|
||||||
|
'properties': {'prop1': 'propvalue1'}}}
|
||||||
|
self.client.images = fixtures
|
||||||
|
self.context.auth_token = False
|
||||||
|
|
||||||
|
expected = {'name': 'image1', 'is_public': True,
|
||||||
|
'properties': {'prop1': 'propvalue1', 'foo': 'bar'}}
|
||||||
|
self.assertRaises(exception.ImageNotFound,
|
||||||
|
self.service.show, self.context, 'image1')
|
||||||
|
|
||||||
|
def test_show_passes_through_to_client_with_authtoken_in_context(self):
|
||||||
|
fixtures = {'image1': {'name': 'image1', 'is_public': False,
|
||||||
|
'foo': 'bar',
|
||||||
|
'properties': {'prop1': 'propvalue1'}}}
|
||||||
|
self.client.images = fixtures
|
||||||
|
self.context.auth_token = True
|
||||||
|
|
||||||
|
expected = {'name': 'image1', 'is_public': False,
|
||||||
|
'properties': {'prop1': 'propvalue1', 'foo': 'bar'}}
|
||||||
|
|
||||||
|
image_meta = self.service.show(self.context, 'image1')
|
||||||
|
self.assertEqual(image_meta, expected)
|
||||||
|
|
||||||
def test_detail_passes_through_to_client(self):
|
def test_detail_passes_through_to_client(self):
|
||||||
fixtures = {'image1': {'id': '1', 'name': 'image1', 'is_public': True,
|
fixtures = {'image1': {'id': '1', 'name': 'image1', 'is_public': True,
|
||||||
'foo': 'bar',
|
'foo': 'bar',
|
||||||
|
|||||||
@@ -161,6 +161,19 @@ class ComputeTestCase(test.TestCase):
|
|||||||
db.security_group_destroy(self.context, group['id'])
|
db.security_group_destroy(self.context, group['id'])
|
||||||
db.instance_destroy(self.context, ref[0]['id'])
|
db.instance_destroy(self.context, ref[0]['id'])
|
||||||
|
|
||||||
|
def test_create_instance_with_invalid_security_group_raises(self):
|
||||||
|
instance_type = instance_types.get_default_instance_type()
|
||||||
|
|
||||||
|
pre_build_len = len(db.instance_get_all(context.get_admin_context()))
|
||||||
|
self.assertRaises(exception.SecurityGroupNotFoundForProject,
|
||||||
|
self.compute_api.create,
|
||||||
|
self.context,
|
||||||
|
instance_type=instance_type,
|
||||||
|
image_href=None,
|
||||||
|
security_group=['this_is_a_fake_sec_group'])
|
||||||
|
self.assertEqual(pre_build_len,
|
||||||
|
len(db.instance_get_all(context.get_admin_context())))
|
||||||
|
|
||||||
def test_create_instance_associates_config_drive(self):
|
def test_create_instance_associates_config_drive(self):
|
||||||
"""Make sure create associates a config drive."""
|
"""Make sure create associates a config drive."""
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ from nova import test
|
|||||||
from nova import utils
|
from nova import utils
|
||||||
from nova.api.ec2 import cloud
|
from nova.api.ec2 import cloud
|
||||||
from nova.compute import power_state
|
from nova.compute import power_state
|
||||||
|
from nova.compute import vm_states
|
||||||
from nova.virt.libvirt import connection
|
from nova.virt.libvirt import connection
|
||||||
from nova.virt.libvirt import firewall
|
from nova.virt.libvirt import firewall
|
||||||
|
|
||||||
@@ -674,8 +675,9 @@ class LibvirtConnTestCase(test.TestCase):
|
|||||||
|
|
||||||
# Preparing data
|
# Preparing data
|
||||||
self.compute = utils.import_object(FLAGS.compute_manager)
|
self.compute = utils.import_object(FLAGS.compute_manager)
|
||||||
instance_dict = {'host': 'fake', 'state': power_state.RUNNING,
|
instance_dict = {'host': 'fake',
|
||||||
'state_description': 'running'}
|
'power_state': power_state.RUNNING,
|
||||||
|
'vm_state': vm_states.ACTIVE}
|
||||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||||
instance_ref = db.instance_update(self.context, instance_ref['id'],
|
instance_ref = db.instance_update(self.context, instance_ref['id'],
|
||||||
instance_dict)
|
instance_dict)
|
||||||
@@ -713,8 +715,8 @@ class LibvirtConnTestCase(test.TestCase):
|
|||||||
self.compute.rollback_live_migration)
|
self.compute.rollback_live_migration)
|
||||||
|
|
||||||
instance_ref = db.instance_get(self.context, instance_ref['id'])
|
instance_ref = db.instance_get(self.context, instance_ref['id'])
|
||||||
self.assertTrue(instance_ref['state_description'] == 'running')
|
self.assertTrue(instance_ref['vm_state'] == vm_states.ACTIVE)
|
||||||
self.assertTrue(instance_ref['state'] == power_state.RUNNING)
|
self.assertTrue(instance_ref['power_state'] == power_state.RUNNING)
|
||||||
volume_ref = db.volume_get(self.context, volume_ref['id'])
|
volume_ref = db.volume_get(self.context, volume_ref['id'])
|
||||||
self.assertTrue(volume_ref['status'] == 'in-use')
|
self.assertTrue(volume_ref['status'] == 'in-use')
|
||||||
|
|
||||||
|
|||||||
@@ -901,3 +901,12 @@ def monkey_patch():
|
|||||||
func = import_class("%s.%s" % (module, key))
|
func = import_class("%s.%s" % (module, key))
|
||||||
setattr(sys.modules[module], key,\
|
setattr(sys.modules[module], key,\
|
||||||
decorator("%s.%s" % (module, key), func))
|
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]
|
||||||
|
|||||||
Reference in New Issue
Block a user