76b58b8f89
This removes personality extension, as well as the rebuild extension point for servers. We add an operation flag to translate extension because personality extension uses different kwarg names depending on the operation. This is done with a set of constants which should prevent typos silently causing failures. A few variables are renamed in servers.py to avoid multiline statements. Part of bp:api-no-more-extensions Change-Id: I47deae0279f85d9a355d1248b6e90af732406514
117 lines
4.3 KiB
Python
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', []))
|