Merge "Refactor server password metadata to avoid direct db usage"
This commit is contained in:
commit
bfd295daed
nova
api
tests
virt/xenapi
@ -15,8 +15,9 @@
|
|||||||
|
|
||||||
from webob import exc
|
from webob import exc
|
||||||
|
|
||||||
|
from nova import conductor
|
||||||
from nova import context
|
from nova import context
|
||||||
from nova import db
|
from nova import utils
|
||||||
|
|
||||||
|
|
||||||
CHUNKS = 4
|
CHUNKS = 4
|
||||||
@ -33,7 +34,7 @@ def extract_password(instance):
|
|||||||
return result or None
|
return result or None
|
||||||
|
|
||||||
|
|
||||||
def set_password(context, instance_uuid, password):
|
def convert_password(context, password):
|
||||||
"""Stores password as system_metadata items.
|
"""Stores password as system_metadata items.
|
||||||
|
|
||||||
Password is stored with the keys 'password_0' -> 'password_3'.
|
Password is stored with the keys 'password_0' -> 'password_3'.
|
||||||
@ -43,10 +44,7 @@ def set_password(context, instance_uuid, password):
|
|||||||
for i in xrange(CHUNKS):
|
for i in xrange(CHUNKS):
|
||||||
meta['password_%d' % i] = password[:CHUNK_LENGTH]
|
meta['password_%d' % i] = password[:CHUNK_LENGTH]
|
||||||
password = password[CHUNK_LENGTH:]
|
password = password[CHUNK_LENGTH:]
|
||||||
db.instance_system_metadata_update(context,
|
return meta
|
||||||
instance_uuid,
|
|
||||||
meta,
|
|
||||||
False)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_password(req, meta_data):
|
def handle_password(req, meta_data):
|
||||||
@ -63,6 +61,12 @@ def handle_password(req, meta_data):
|
|||||||
if (req.content_length > MAX_SIZE or len(req.body) > MAX_SIZE):
|
if (req.content_length > MAX_SIZE or len(req.body) > MAX_SIZE):
|
||||||
msg = _("Request is too large.")
|
msg = _("Request is too large.")
|
||||||
raise exc.HTTPBadRequest(explanation=msg)
|
raise exc.HTTPBadRequest(explanation=msg)
|
||||||
set_password(ctxt, meta_data.uuid, req.body)
|
|
||||||
|
conductor_api = conductor.API()
|
||||||
|
instance = conductor_api.instance_get_by_uuid(ctxt, meta_data.uuid)
|
||||||
|
sys_meta = utils.metadata_to_dict(instance['system_metadata'])
|
||||||
|
sys_meta.update(convert_password(ctxt, req.body))
|
||||||
|
conductor_api.instance_update(ctxt, meta_data.uuid,
|
||||||
|
system_metadata=sys_meta)
|
||||||
else:
|
else:
|
||||||
raise exc.HTTPBadRequest()
|
raise exc.HTTPBadRequest()
|
||||||
|
@ -24,6 +24,7 @@ from nova.api.openstack import extensions
|
|||||||
from nova.api.openstack import wsgi
|
from nova.api.openstack import wsgi
|
||||||
from nova.api.openstack import xmlutil
|
from nova.api.openstack import xmlutil
|
||||||
from nova import compute
|
from nova import compute
|
||||||
|
from nova import db
|
||||||
from nova import exception
|
from nova import exception
|
||||||
|
|
||||||
|
|
||||||
@ -62,7 +63,9 @@ class ServerPasswordController(object):
|
|||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
authorize(context)
|
authorize(context)
|
||||||
instance = self._get_instance(context, server_id)
|
instance = self._get_instance(context, server_id)
|
||||||
password.set_password(context, instance['uuid'], None)
|
meta = password.convert_password(context, None)
|
||||||
|
db.instance_system_metadata_update(context, instance['uuid'],
|
||||||
|
meta, False)
|
||||||
|
|
||||||
|
|
||||||
class Server_password(extensions.ExtensionDescriptor):
|
class Server_password(extensions.ExtensionDescriptor):
|
||||||
|
@ -40,11 +40,12 @@ class ServerPasswordTest(test.TestCase):
|
|||||||
def fake_extract_password(instance):
|
def fake_extract_password(instance):
|
||||||
return self.password
|
return self.password
|
||||||
|
|
||||||
def fake_set_password(context, instance_uuid, password):
|
def fake_convert_password(context, password):
|
||||||
self.password = password
|
self.password = password
|
||||||
|
return {}
|
||||||
|
|
||||||
self.stubs.Set(password, 'extract_password', fake_extract_password)
|
self.stubs.Set(password, 'extract_password', fake_extract_password)
|
||||||
self.stubs.Set(password, 'set_password', fake_set_password)
|
self.stubs.Set(password, 'convert_password', fake_convert_password)
|
||||||
self.flags(
|
self.flags(
|
||||||
osapi_compute_extension=[
|
osapi_compute_extension=[
|
||||||
'nova.api.openstack.compute.contrib.select_extensions'],
|
'nova.api.openstack.compute.contrib.select_extensions'],
|
||||||
|
@ -549,6 +549,7 @@ class MetadataPasswordTestCase(test.TestCase):
|
|||||||
self.instance = copy.copy(INSTANCES[0])
|
self.instance = copy.copy(INSTANCES[0])
|
||||||
self.mdinst = fake_InstanceMetadata(self.stubs, self.instance,
|
self.mdinst = fake_InstanceMetadata(self.stubs, self.instance,
|
||||||
address=None, sgroups=None)
|
address=None, sgroups=None)
|
||||||
|
self.flags(use_local=True, group='conductor')
|
||||||
|
|
||||||
def test_get_password(self):
|
def test_get_password(self):
|
||||||
request = webob.Request.blank('')
|
request = webob.Request.blank('')
|
||||||
@ -566,8 +567,16 @@ class MetadataPasswordTestCase(test.TestCase):
|
|||||||
request = webob.Request.blank('')
|
request = webob.Request.blank('')
|
||||||
request.method = 'POST'
|
request.method = 'POST'
|
||||||
request.body = val
|
request.body = val
|
||||||
self.stubs.Set(db, 'instance_system_metadata_update',
|
self.stubs.Set(db, 'instance_get_by_uuid',
|
||||||
lambda *a, **kw: None)
|
lambda *a, **kw: {'system_metadata': []})
|
||||||
|
|
||||||
|
def fake_instance_update(context, uuid, updates):
|
||||||
|
self.assertIn('system_metadata', updates)
|
||||||
|
self.assertIn('password_0', updates['system_metadata'])
|
||||||
|
return self.instance, self.instance
|
||||||
|
|
||||||
|
self.stubs.Set(db, 'instance_update_and_get_original',
|
||||||
|
fake_instance_update)
|
||||||
password.handle_password(request, self.mdinst)
|
password.handle_password(request, self.mdinst)
|
||||||
|
|
||||||
def test_set_password(self):
|
def test_set_password(self):
|
||||||
|
@ -123,8 +123,9 @@ def _get_agent_version(session, instance, vm_ref):
|
|||||||
|
|
||||||
|
|
||||||
class XenAPIBasedAgent(object):
|
class XenAPIBasedAgent(object):
|
||||||
def __init__(self, session, instance, vm_ref):
|
def __init__(self, session, virtapi, instance, vm_ref):
|
||||||
self.session = session
|
self.session = session
|
||||||
|
self.virtapi = virtapi
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.vm_ref = vm_ref
|
self.vm_ref = vm_ref
|
||||||
|
|
||||||
@ -212,9 +213,13 @@ class XenAPIBasedAgent(object):
|
|||||||
|
|
||||||
sshkey = self.instance.get('key_data')
|
sshkey = self.instance.get('key_data')
|
||||||
if sshkey:
|
if sshkey:
|
||||||
|
ctxt = context.get_admin_context()
|
||||||
enc = crypto.ssh_encrypt_text(sshkey, new_pass)
|
enc = crypto.ssh_encrypt_text(sshkey, new_pass)
|
||||||
password.set_password(context.get_admin_context(),
|
sys_meta = utils.metadata_to_dict(self.instance['system_metadata'])
|
||||||
self.instance['uuid'], base64.b64encode(enc))
|
sys_meta.update(password.convert_password(ctxt,
|
||||||
|
base64.b64encode(enc)))
|
||||||
|
self.virtapi.instance_update(ctxt, self.instance['uuid'],
|
||||||
|
{'system_metadata': sys_meta})
|
||||||
|
|
||||||
return resp['message']
|
return resp['message']
|
||||||
|
|
||||||
|
@ -176,7 +176,8 @@ class VMOps(object):
|
|||||||
|
|
||||||
def _get_agent(self, instance, vm_ref):
|
def _get_agent(self, instance, vm_ref):
|
||||||
if self.agent_enabled:
|
if self.agent_enabled:
|
||||||
return xapi_agent.XenAPIBasedAgent(self._session, instance, vm_ref)
|
return xapi_agent.XenAPIBasedAgent(self._session, self._virtapi,
|
||||||
|
instance, vm_ref)
|
||||||
raise exception.NovaException(_("Error: Agent is disabled"))
|
raise exception.NovaException(_("Error: Agent is disabled"))
|
||||||
|
|
||||||
def list_instances(self):
|
def list_instances(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user