
Replace the following items with Python 3 style code. - six.moves.configparser - six.moves.StringIO - six.moves.cStringIO - six.moves.urllib - six.moves.builtins - six.moves.range - six.moves.xmlrpc_client - six.moves.http_client - six.moves.http_cookies - six.moves.queue - six.moves.zip - six.moves.reload_module - six.StringIO - six.BytesIO Subsequent patches will replace other six usages. Change-Id: Ib2c406327fef2fb4868d8050fc476a7d17706e23 Implements: blueprint six-removal Signed-off-by: Takashi Natsume <takanattie@gmail.com>
89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
# Copyright 2012 Nebula, Inc.
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
from webob import exc
|
|
|
|
import nova.conf
|
|
from nova import context
|
|
from nova import exception
|
|
from nova.i18n import _
|
|
from nova import objects
|
|
from nova import utils
|
|
|
|
|
|
CONF = nova.conf.CONF
|
|
|
|
CHUNKS = 4
|
|
CHUNK_LENGTH = 255
|
|
MAX_SIZE = CHUNKS * CHUNK_LENGTH
|
|
|
|
|
|
def extract_password(instance):
|
|
result = ''
|
|
sys_meta = utils.instance_sys_meta(instance)
|
|
for key in sorted(sys_meta.keys()):
|
|
if key.startswith('password_'):
|
|
result += sys_meta[key]
|
|
return result or None
|
|
|
|
|
|
def convert_password(context, password):
|
|
"""Stores password as system_metadata items.
|
|
|
|
Password is stored with the keys 'password_0' -> 'password_3'.
|
|
"""
|
|
password = password or ''
|
|
if isinstance(password, bytes):
|
|
password = password.decode('utf-8')
|
|
|
|
meta = {}
|
|
for i in range(CHUNKS):
|
|
meta['password_%d' % i] = password[:CHUNK_LENGTH]
|
|
password = password[CHUNK_LENGTH:]
|
|
return meta
|
|
|
|
|
|
def handle_password(req, meta_data):
|
|
ctxt = context.get_admin_context()
|
|
if req.method == 'GET':
|
|
return meta_data.password
|
|
elif req.method == 'POST':
|
|
# NOTE(vish): The conflict will only happen once the metadata cache
|
|
# updates, but it isn't a huge issue if it can be set for
|
|
# a short window.
|
|
if meta_data.password:
|
|
raise exc.HTTPConflict()
|
|
if (req.content_length > MAX_SIZE or len(req.body) > MAX_SIZE):
|
|
msg = _("Request is too large.")
|
|
raise exc.HTTPBadRequest(explanation=msg)
|
|
|
|
if CONF.api.local_metadata_per_cell:
|
|
instance = objects.Instance.get_by_uuid(ctxt, meta_data.uuid)
|
|
else:
|
|
im = objects.InstanceMapping.get_by_instance_uuid(
|
|
ctxt, meta_data.uuid)
|
|
with context.target_cell(ctxt, im.cell_mapping) as cctxt:
|
|
try:
|
|
instance = objects.Instance.get_by_uuid(
|
|
cctxt, meta_data.uuid)
|
|
except exception.InstanceNotFound as e:
|
|
raise exc.HTTPBadRequest(explanation=e.format_message())
|
|
|
|
instance.system_metadata.update(convert_password(ctxt, req.body))
|
|
instance.save()
|
|
else:
|
|
msg = _("GET and POST only are supported.")
|
|
raise exc.HTTPBadRequest(explanation=msg)
|