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', []))
|