nova/nova/api/openstack/compute/helpers.py

117 lines
4.3 KiB
Python

# Copyright 2016 HPE, Inc.
#
# 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 oslo_utils import strutils
from webob import exc
from nova.i18n import _
API_DISK_CONFIG = "OS-DCF:diskConfig"
API_ACCESS_V4 = "accessIPv4"
API_ACCESS_V6 = "accessIPv6"
# possible ops
CREATE = 'create'
UPDATE = 'update'
REBUILD = 'rebuild'
RESIZE = 'resize'
def disk_config_from_api(value):
if value == 'AUTO':
return True
elif value == 'MANUAL':
return False
else:
msg = _("%s must be either 'MANUAL' or 'AUTO'.") % API_DISK_CONFIG
raise exc.HTTPBadRequest(explanation=msg)
def get_injected_files(personality):
"""Create a list of injected files from the personality attribute.
At this time, injected_files must be formatted as a list of
(file_path, file_content) pairs for compatibility with the
underlying compute service.
"""
injected_files = []
for item in personality:
injected_files.append((item['path'], item['contents']))
return injected_files
def translate_attributes(op, server_dict, operation_kwargs):
"""Translate REST attributes on create to server object kwargs.
Our REST API is relatively fixed, but internal representations
change over time, this is a translator for inbound REST request
attributes that modifies the server dict that we get and adds
appropriate attributes to ``operation_kwargs`` that will be passed
down to instance objects later.
It's done in a common function as this is used for create / resize
/ rebuild / update
The ``op`` is the operation that we are transforming, because
there are times when we translate differently for different
operations. (Yes, it's a little nuts, but legacy... )
The ``server_dict`` is a representation of the server in
question. During ``create`` and ``update`` operations this will
actually be the ``server`` element of the request body.
During actions, such as ``rebuild`` and ``resize`` this will be
the attributes passed to the action object during the
operation. This is equivalent to the ``server`` object.
Not all operations support all attributes listed here. Which is
why it's important to only set operation_kwargs if there is
something to set. Input validation will ensure that we are only
operating on appropriate attributes for each operation.
"""
# Disk config
auto_disk_config_raw = server_dict.pop(API_DISK_CONFIG, None)
if auto_disk_config_raw is not None:
auto_disk_config = disk_config_from_api(auto_disk_config_raw)
operation_kwargs['auto_disk_config'] = auto_disk_config
if API_ACCESS_V4 in server_dict:
operation_kwargs['access_ip_v4'] = server_dict.pop(API_ACCESS_V4)
if API_ACCESS_V6 in server_dict:
operation_kwargs['access_ip_v6'] = server_dict.pop(API_ACCESS_V6)
# This is only ever expected during rebuild operations, and only
# does anything with Ironic driver. It also demonstrates the lack
# of understanding of the word ephemeral.
if 'preserve_ephemeral' in server_dict and op == REBUILD:
preserve = strutils.bool_from_string(
server_dict.pop('preserve_ephemeral'), strict=True)
operation_kwargs['preserve_ephemeral'] = preserve
# yes, we use different kwargs, this goes all the way back to
# commit cebc98176926f57016a508d5c59b11f55dfcf2b3.
if 'personality' in server_dict:
if op == REBUILD:
operation_kwargs['files_to_inject'] = get_injected_files(
server_dict.pop('personality'))
# NOTE(sdague): the deprecated hooks infrastructure doesn't
# function if injected files is not defined as a list. Once hooks
# are removed, this should go back inside the personality
# conditional above.
if op == CREATE:
operation_kwargs['injected_files'] = get_injected_files(
server_dict.pop('personality', []))