Coverage for nova/api/openstack/compute/helpers.py: 95%
39 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-24 11:16 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-24 11:16 +0000
1# Copyright 2016 HPE, Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
16from oslo_utils import strutils
17from webob import exc
19from nova.i18n import _
21API_DISK_CONFIG = "OS-DCF:diskConfig"
22API_ACCESS_V4 = "accessIPv4"
23API_ACCESS_V6 = "accessIPv6"
25# possible ops
26CREATE = 'create'
27UPDATE = 'update'
28REBUILD = 'rebuild'
29RESIZE = 'resize'
32def disk_config_from_api(value):
33 if value == 'AUTO':
34 return True
35 elif value == 'MANUAL': 35 ↛ 38line 35 didn't jump to line 38 because the condition on line 35 was always true
36 return False
37 else:
38 msg = _("%s must be either 'MANUAL' or 'AUTO'.") % API_DISK_CONFIG
39 raise exc.HTTPBadRequest(explanation=msg)
42def get_injected_files(personality):
43 """Create a list of injected files from the personality attribute.
45 At this time, injected_files must be formatted as a list of
46 (file_path, file_content) pairs for compatibility with the
47 underlying compute service.
48 """
49 injected_files = []
50 for item in personality:
51 injected_files.append((item['path'], item['contents']))
52 return injected_files
55def translate_attributes(op, server_dict, operation_kwargs):
56 """Translate REST attributes on create to server object kwargs.
58 Our REST API is relatively fixed, but internal representations
59 change over time, this is a translator for inbound REST request
60 attributes that modifies the server dict that we get and adds
61 appropriate attributes to ``operation_kwargs`` that will be passed
62 down to instance objects later.
64 It's done in a common function as this is used for create / resize
65 / rebuild / update
67 The ``op`` is the operation that we are transforming, because
68 there are times when we translate differently for different
69 operations. (Yes, it's a little nuts, but legacy... )
71 The ``server_dict`` is a representation of the server in
72 question. During ``create`` and ``update`` operations this will
73 actually be the ``server`` element of the request body.
75 During actions, such as ``rebuild`` and ``resize`` this will be
76 the attributes passed to the action object during the
77 operation. This is equivalent to the ``server`` object.
79 Not all operations support all attributes listed here. Which is
80 why it's important to only set operation_kwargs if there is
81 something to set. Input validation will ensure that we are only
82 operating on appropriate attributes for each operation.
84 """
85 # Disk config
86 auto_disk_config_raw = server_dict.pop(API_DISK_CONFIG, None)
87 if auto_disk_config_raw is not None:
88 auto_disk_config = disk_config_from_api(auto_disk_config_raw)
89 operation_kwargs['auto_disk_config'] = auto_disk_config
91 if API_ACCESS_V4 in server_dict:
92 operation_kwargs['access_ip_v4'] = server_dict.pop(API_ACCESS_V4)
93 if API_ACCESS_V6 in server_dict:
94 operation_kwargs['access_ip_v6'] = server_dict.pop(API_ACCESS_V6)
96 # This is only ever expected during rebuild operations, and only
97 # does anything with Ironic driver. It also demonstrates the lack
98 # of understanding of the word ephemeral.
99 if 'preserve_ephemeral' in server_dict and op == REBUILD:
100 preserve = strutils.bool_from_string(
101 server_dict.pop('preserve_ephemeral'), strict=True)
102 operation_kwargs['preserve_ephemeral'] = preserve
104 # yes, we use different kwargs, this goes all the way back to
105 # commit cebc98176926f57016a508d5c59b11f55dfcf2b3.
106 if 'personality' in server_dict:
107 if op == REBUILD:
108 operation_kwargs['files_to_inject'] = get_injected_files(
109 server_dict.pop('personality'))
110 # NOTE(sdague): the deprecated hooks infrastructure doesn't
111 # function if injected files is not defined as a list. Once hooks
112 # are removed, this should go back inside the personality
113 # conditional above.
114 if op == CREATE:
115 operation_kwargs['injected_files'] = get_injected_files(
116 server_dict.pop('personality', []))