summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2011-12-22 12:59:00 +0000
committerGerrit Code Review <review@openstack.org>2011-12-22 12:59:00 +0000
commit5bcaecdc7d42b8a4aa2f16e96c064869438d6a12 (patch)
tree85cde1b8379e320621a949240d767dfd07e0b17e
parentb2f36879b0d5f264ae2a9dd49fb893c6fbe25068 (diff)
parentadcfd491308a98107e82b9f0595e0bf2f37b5a54 (diff)
downloadnova-5bcaecdc7d42b8a4aa2f16e96c064869438d6a12.tar.gz
nova-5bcaecdc7d42b8a4aa2f16e96c064869438d6a12.tar.xz
nova-5bcaecdc7d42b8a4aa2f16e96c064869438d6a12.zip
Merge "Allow accessIPv4 and accessIPv6 on rebuild action"
-rw-r--r--nova/api/openstack/v2/servers.py66
-rw-r--r--nova/compute/api.py17
-rw-r--r--nova/tests/api/openstack/v2/test_server_actions.py53
-rw-r--r--nova/tests/integrated/test_servers.py92
4 files changed, 113 insertions, 115 deletions
diff --git a/nova/api/openstack/v2/servers.py b/nova/api/openstack/v2/servers.py
index 51ccaadde..cb0ece1f0 100644
--- a/nova/api/openstack/v2/servers.py
+++ b/nova/api/openstack/v2/servers.py
@@ -16,10 +16,10 @@
import base64
import os
+from xml.dom import minidom
from webob import exc
import webob
-from xml.dom import minidom
from nova.api.openstack import common
from nova.api.openstack.v2 import ips
@@ -731,46 +731,68 @@ class Controller(wsgi.Controller):
return self._resize(req, id, flavor_ref)
def _action_rebuild(self, info, request, instance_id):
- context = request.environ['nova.context']
- instance = self._get_server(context, instance_id)
+ """Rebuild an instance with the given attributes"""
+ try:
+ body = info['rebuild']
+ except (KeyError, TypeError):
+ raise exc.HTTPBadRequest(_("Invalid request body"))
try:
- image_href = info["rebuild"]["imageRef"]
+ image_href = body["imageRef"]
except (KeyError, TypeError):
msg = _("Could not parse imageRef from request.")
- LOG.debug(msg)
raise exc.HTTPBadRequest(explanation=msg)
- personality = info["rebuild"].get("personality", [])
- injected_files = []
- if personality:
- injected_files = self._get_injected_files(personality)
+ try:
+ password = body['adminPass']
+ except (KeyError, TypeError):
+ password = utils.generate_password(FLAGS.password_length)
- metadata = info["rebuild"].get("metadata")
- name = info["rebuild"].get("name")
+ context = request.environ['nova.context']
+ instance = self._get_server(context, instance_id)
+
+ attr_map = {
+ 'personality': 'files_to_inject',
+ 'name': 'display_name',
+ 'accessIPv4': 'access_ip_v4',
+ 'accessIPv6': 'access_ip_v6',
+ 'metadata': 'metadata',
+ }
- if metadata:
- self._validate_metadata(metadata)
+ kwargs = {}
- if 'rebuild' in info and 'adminPass' in info['rebuild']:
- password = info['rebuild']['adminPass']
- else:
- password = utils.generate_password(FLAGS.password_length)
+ for request_attribute, instance_attribute in attr_map.items():
+ try:
+ kwargs[instance_attribute] = body[request_attribute]
+ except (KeyError, TypeError):
+ pass
+
+ self._validate_metadata(kwargs.get('metadata', {}))
+
+ if 'files_to_inject' in kwargs:
+ personality = kwargs['files_to_inject']
+ kwargs['files_to_inject'] = self._get_injected_files(personality)
try:
- self.compute_api.rebuild(context, instance, image_href,
- password, name=name, metadata=metadata,
- files_to_inject=injected_files)
+ self.compute_api.rebuild(context,
+ instance,
+ image_href,
+ password,
+ **kwargs)
+
except exception.RebuildRequiresActiveInstance:
- msg = _("Instance %s must be active to rebuild.") % instance_id
+ msg = _("Instance must be active to rebuild.")
raise exc.HTTPConflict(explanation=msg)
except exception.InstanceNotFound:
- msg = _("Instance %s could not be found") % instance_id
+ msg = _("Instance could not be found")
raise exc.HTTPNotFound(explanation=msg)
instance = self._get_server(context, instance_id)
+
self._add_instance_faults(context, [instance])
view = self._view_builder.show(request, instance)
+
+ # Add on the adminPass attribute since the view doesn't do it
view['server']['adminPass'] = password
return view
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 61394233a..70e9876ae 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -1194,25 +1194,22 @@ class API(base.Base):
@check_instance_state(vm_state=[vm_states.ACTIVE],
task_state=[None, task_states.RESIZE_VERIFY])
@scheduler_api.reroute_compute("rebuild")
- def rebuild(self, context, instance, image_href, admin_password,
- name=None, metadata=None, files_to_inject=None):
- """Rebuild the given instance with the provided metadata."""
- name = name or instance["display_name"]
-
- files_to_inject = files_to_inject or []
- metadata = metadata or {}
+ def rebuild(self, context, instance, image_href, admin_password, **kwargs):
+ """Rebuild the given instance with the provided attributes."""
+ files_to_inject = kwargs.pop('files_to_inject', [])
self._check_injected_file_quota(context, files_to_inject)
+
+ metadata = kwargs.get('metadata', {})
self._check_metadata_properties_quota(context, metadata)
self.update(context,
instance,
- metadata=metadata,
- display_name=name,
image_ref=image_href,
vm_state=vm_states.REBUILDING,
task_state=None,
- progress=0)
+ progress=0,
+ **kwargs)
rebuild_params = {
"new_pass": admin_password,
diff --git a/nova/tests/api/openstack/v2/test_server_actions.py b/nova/tests/api/openstack/v2/test_server_actions.py
index 1c1c2b986..9a96c7337 100644
--- a/nova/tests/api/openstack/v2/test_server_actions.py
+++ b/nova/tests/api/openstack/v2/test_server_actions.py
@@ -16,6 +16,7 @@
import base64
import datetime
+import mox
import stubout
import webob
@@ -69,7 +70,8 @@ def return_server_with_uuid_and_state(vm_state, task_state=None):
def stub_instance(id, metadata=None, image_ref="10", flavor_id="1",
- name=None, vm_state=None, task_state=None, uuid=None):
+ name=None, vm_state=None, task_state=None, uuid=None,
+ access_ip_v4="", access_ip_v6=""):
if metadata is not None:
metadata_items = [{'key':k, 'value':v} for k, v in metadata.items()]
else:
@@ -113,8 +115,8 @@ def stub_instance(id, metadata=None, image_ref="10", flavor_id="1",
"display_description": "",
"locked": False,
"metadata": metadata_items,
- "access_ip_v4": "",
- "access_ip_v6": "",
+ "access_ip_v4": access_ip_v4,
+ "access_ip_v6": access_ip_v6,
"uuid": uuid,
"virtual_interfaces": [],
"progress": 0,
@@ -253,7 +255,7 @@ class ServerActionsControllerTest(test.TestCase):
self.assertRaises(webob.exc.HTTPNotFound, self.controller.action,
req, str(utils.gen_uuid()), body)
- def test_server_rebuild_accepted_minimum(self):
+ def test_rebuild_accepted_minimum(self):
new_return_server = return_server_with_attributes(image_ref='2')
self.stubs.Set(nova.db, 'instance_get', new_return_server)
@@ -270,7 +272,7 @@ class ServerActionsControllerTest(test.TestCase):
self.assertEqual(len(body['server']['adminPass']),
FLAGS.password_length)
- def test_server_rebuild_rejected_when_building(self):
+ def test_rebuild_rejected_when_building(self):
body = {
"rebuild": {
"imageRef": "http://localhost/images/2",
@@ -286,7 +288,7 @@ class ServerActionsControllerTest(test.TestCase):
self.assertRaises(webob.exc.HTTPConflict,
self.controller.action, req, FAKE_UUID, body)
- def test_server_rebuild_accepted_with_metadata(self):
+ def test_rebuild_accepted_with_metadata(self):
metadata = {'new': 'metadata'}
new_return_server = return_server_with_attributes(metadata=metadata)
@@ -304,7 +306,7 @@ class ServerActionsControllerTest(test.TestCase):
self.assertEqual(body['server']['metadata'], metadata)
- def test_server_rebuild_accepted_with_bad_metadata(self):
+ def test_rebuild_accepted_with_bad_metadata(self):
body = {
"rebuild": {
"imageRef": "http://localhost/images/2",
@@ -316,7 +318,7 @@ class ServerActionsControllerTest(test.TestCase):
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller.action, req, FAKE_UUID, body)
- def test_server_rebuild_bad_entity(self):
+ def test_rebuild_bad_entity(self):
body = {
"rebuild": {
"imageId": 2,
@@ -327,7 +329,7 @@ class ServerActionsControllerTest(test.TestCase):
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller.action, req, FAKE_UUID, body)
- def test_server_rebuild_bad_personality(self):
+ def test_rebuild_bad_personality(self):
body = {
"rebuild": {
"imageRef": "http://localhost/images/2",
@@ -342,7 +344,7 @@ class ServerActionsControllerTest(test.TestCase):
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller.action, req, FAKE_UUID, body)
- def test_server_rebuild_personality(self):
+ def test_rebuild_personality(self):
body = {
"rebuild": {
"imageRef": "http://localhost/images/2",
@@ -358,7 +360,7 @@ class ServerActionsControllerTest(test.TestCase):
self.assertTrue('personality' not in body['server'])
- def test_server_rebuild_admin_pass(self):
+ def test_rebuild_admin_pass(self):
new_return_server = return_server_with_attributes(image_ref='2')
self.stubs.Set(nova.db, 'instance_get', new_return_server)
@@ -375,7 +377,7 @@ class ServerActionsControllerTest(test.TestCase):
self.assertEqual(body['server']['image']['id'], '2')
self.assertEqual(body['server']['adminPass'], 'asdf')
- def test_server_rebuild_server_not_found(self):
+ def test_rebuild_server_not_found(self):
def server_not_found(self, instance_id):
raise exception.InstanceNotFound(instance_id=instance_id)
self.stubs.Set(nova.db, 'instance_get', server_not_found)
@@ -390,6 +392,33 @@ class ServerActionsControllerTest(test.TestCase):
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.action, req, FAKE_UUID, body)
+ def test_rebuild_accessIP(self):
+ attributes = {
+ 'access_ip_v4': '172.19.0.1',
+ 'access_ip_v6': 'fe80::1',
+ }
+
+ body = {
+ "rebuild": {
+ "imageRef": "http://localhost/images/2",
+ "accessIPv4": "172.19.0.1",
+ "accessIPv6": "fe80::1",
+ },
+ }
+
+ update = self.mox.CreateMockAnything()
+ self.stubs.Set(nova.compute.API, 'update', update)
+ req = fakes.HTTPRequest.blank(self.url)
+ context = req.environ['nova.context']
+ update(context, mox.IgnoreArg(),
+ image_ref='http://localhost/images/2',
+ vm_state=vm_states.REBUILDING,
+ task_state=None, progress=0, **attributes).AndReturn(None)
+ self.mox.ReplayAll()
+
+ self.controller.action(req, FAKE_UUID, body)
+ self.mox.VerifyAll()
+
def test_resize_server(self):
body = dict(resize=dict(flavorRef="http://localhost/3"))
diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py
index 556b74abe..42deee413 100644
--- a/nova/tests/integrated/test_servers.py
+++ b/nova/tests/integrated/test_servers.py
@@ -312,47 +312,19 @@ class ServersTest(integrated_helpers._IntegratedTestBase):
self._delete_server(created_server_id)
def test_create_and_rebuild_server(self):
- """Rebuild a server."""
+ """Rebuild a server with metadata."""
self.flags(stub_network=True)
# create a server with initially has no metadata
server = self._build_minimal_create_server_request()
server_post = {'server': server}
- created_server = self.api.post_server(server_post)
- LOG.debug("created_server: %s" % created_server)
- self.assertTrue(created_server['id'])
- created_server_id = created_server['id']
-
- created_server = self._wait_for_state_change(created_server, 'BUILD')
-
- # rebuild the server with metadata
- post = {}
- post['rebuild'] = {
- "imageRef": "c905cedb-7281-47e4-8a62-f26bc5fc4c77",
- "name": "blah",
- }
-
- self.api.post_server_action(created_server_id, post)
- LOG.debug("rebuilt server: %s" % created_server)
- self.assertTrue(created_server['id'])
-
- found_server = self.api.get_server(created_server_id)
- self.assertEqual(created_server_id, found_server['id'])
- self.assertEqual({}, found_server.get('metadata'))
- self.assertEqual('blah', found_server.get('name'))
- self.assertEqual(post['rebuild']['imageRef'],
- found_server.get('image')['id'])
- # Cleanup
- self._delete_server(created_server_id)
+ metadata = {}
+ for i in range(30):
+ metadata['key_%s' % i] = 'value_%s' % i
- def test_create_and_rebuild_server_with_metadata(self):
- """Rebuild a server with metadata."""
- self.flags(stub_network=True)
+ server_post['server']['metadata'] = metadata
- # create a server with initially has no metadata
- server = self._build_minimal_create_server_request()
- server_post = {'server': server}
created_server = self.api.post_server(server_post)
LOG.debug("created_server: %s" % created_server)
self.assertTrue(created_server['id'])
@@ -360,70 +332,48 @@ class ServersTest(integrated_helpers._IntegratedTestBase):
created_server = self._wait_for_state_change(created_server, 'BUILD')
- # rebuild the server with metadata
+ # rebuild the server with metadata and other server attributes
post = {}
post['rebuild'] = {
"imageRef": "76fa36fc-c930-4bf3-8c8a-ea2a2420deb6",
"name": "blah",
+ "accessIPv4": "172.19.0.2",
+ "accessIPv6": "fe80::2",
+ "metadata": {'some': 'thing'},
}
- metadata = {}
- for i in range(30):
- metadata['key_%s' % i] = 'value_%s' % i
-
- post['rebuild']['metadata'] = metadata
-
self.api.post_server_action(created_server_id, post)
LOG.debug("rebuilt server: %s" % created_server)
self.assertTrue(created_server['id'])
found_server = self.api.get_server(created_server_id)
self.assertEqual(created_server_id, found_server['id'])
- self.assertEqual(metadata, found_server.get('metadata'))
+ self.assertEqual({'some': 'thing'}, found_server.get('metadata'))
self.assertEqual('blah', found_server.get('name'))
+ self.assertEqual(post['rebuild']['imageRef'],
+ found_server.get('image')['id'])
+ self.assertEqual('172.19.0.2', found_server['accessIPv4'])
+ self.assertEqual('fe80::2', found_server['accessIPv6'])
- # Cleanup
- self._delete_server(created_server_id)
-
- def test_create_and_rebuild_server_with_metadata_removal(self):
- """Rebuild a server with metadata."""
- self.flags(stub_network=True)
-
- # create a server with initially has no metadata
- server = self._build_minimal_create_server_request()
- server_post = {'server': server}
-
- metadata = {}
- for i in range(30):
- metadata['key_%s' % i] = 'value_%s' % i
-
- server_post['server']['metadata'] = metadata
-
- created_server = self.api.post_server(server_post)
- LOG.debug("created_server: %s" % created_server)
- self.assertTrue(created_server['id'])
- created_server_id = created_server['id']
-
- created_server = self._wait_for_state_change(created_server, 'BUILD')
-
- # rebuild the server with metadata
+ # rebuild the server with empty metadata and nothing else
post = {}
post['rebuild'] = {
"imageRef": "76fa36fc-c930-4bf3-8c8a-ea2a2420deb6",
- "name": "blah",
+ "metadata": {},
}
- metadata = {}
- post['rebuild']['metadata'] = metadata
-
self.api.post_server_action(created_server_id, post)
LOG.debug("rebuilt server: %s" % created_server)
self.assertTrue(created_server['id'])
found_server = self.api.get_server(created_server_id)
self.assertEqual(created_server_id, found_server['id'])
- self.assertEqual(metadata, found_server.get('metadata'))
+ self.assertEqual({}, found_server.get('metadata'))
self.assertEqual('blah', found_server.get('name'))
+ self.assertEqual(post['rebuild']['imageRef'],
+ found_server.get('image')['id'])
+ self.assertEqual('172.19.0.2', found_server['accessIPv4'])
+ self.assertEqual('fe80::2', found_server['accessIPv6'])
# Cleanup
self._delete_server(created_server_id)