2
# Licensed under the Apache License, Version 2.0 (the "License"); you may
3
# not use this file except in compliance with the License. You may obtain
4
# a copy of the License at
6
# http://www.apache.org/licenses/LICENSE-2.0
8
# Unless required by applicable law or agreed to in writing, software
9
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
# License for the specific language governing permissions and limitations
14
from oslo_log import log as logging
16
from heat.common.i18n import _
17
from heat.engine import attributes
18
from heat.engine import constraints
19
from heat.engine import properties
20
from heat.engine import resource
21
from heat.engine import support
22
from heat.rpc import api as rpc_api
24
LOG = logging.getLogger(__name__)
27
class SoftwareConfig(resource.Resource):
29
A resource for describing and storing software configuration.
31
The software_configs API which backs this resource creates immutable
32
configs, so any change to the template resource definition will result
33
in a new config being created, and the old one being deleted.
35
Configs can be defined in the same template which uses them, or they can
36
be created in one stack, and passed to another stack via a parameter.
38
A config resource can be referenced in other resource properties which
39
are config-aware. This includes the properties OS::Nova::Server user_data,
40
OS::Heat::SoftwareDeployment config and OS::Heat::MultipartMime parts
43
Along with the config script itself, this resource can define schemas for
44
inputs and outputs which the config script is expected to consume and
45
produce. Inputs and outputs are optional and will map to concepts which
46
are specific to the configuration tool being used.
49
support_status = support.SupportStatus(version='2014.1')
52
GROUP, CONFIG, OPTIONS, INPUTS, OUTPUTS
54
'group', 'config', 'options', 'inputs', 'outputs'
58
NAME, DESCRIPTION, TYPE, DEFAULT, ERROR_OUTPUT
60
'name', 'description', 'type', 'default', 'error_output'
70
NAME: properties.Schema(
71
properties.Schema.STRING,
72
_('Name of the input.'),
75
DESCRIPTION: properties.Schema(
76
properties.Schema.STRING,
77
_('Description of the input.')
79
TYPE: properties.Schema(
80
properties.Schema.STRING,
81
_('Type of the value of the input.'),
83
constraints=[constraints.AllowedValues((
84
'String', 'Number', 'CommaDelimitedList', 'Json'))]
86
DEFAULT: properties.Schema(
87
properties.Schema.STRING,
88
_('Default value for the input if none is specified.'),
93
NAME: properties.Schema(
94
properties.Schema.STRING,
95
_('Name of the output.'),
98
DESCRIPTION: properties.Schema(
99
properties.Schema.STRING,
100
_('Description of the output.')
102
TYPE: properties.Schema(
103
properties.Schema.STRING,
104
_('Type of the value of the output.'),
106
constraints=[constraints.AllowedValues((
107
'String', 'Number', 'CommaDelimitedList', 'Json'))]
109
ERROR_OUTPUT: properties.Schema(
110
properties.Schema.BOOLEAN,
111
_('Denotes that the deployment is in an error state if this '
112
'output has a value.'),
117
properties_schema = {
118
GROUP: properties.Schema(
119
properties.Schema.STRING,
120
_('Namespace to group this software config by when delivered to '
121
'a server. This may imply what configuration tool is going to '
122
'perform the configuration.'),
123
default='Heat::Ungrouped'
125
CONFIG: properties.Schema(
126
properties.Schema.STRING,
127
_('Configuration script or manifest which specifies what actual '
128
'configuration is performed.'),
130
OPTIONS: properties.Schema(
131
properties.Schema.MAP,
132
_('Map containing options specific to the configuration '
133
'management tool used by this resource.'),
135
INPUTS: properties.Schema(
136
properties.Schema.LIST,
137
_('Schema representing the inputs that this software config is '
139
schema=properties.Schema(properties.Schema.MAP,
142
OUTPUTS: properties.Schema(
143
properties.Schema.LIST,
144
_('Schema representing the outputs that this software config '
146
schema=properties.Schema(properties.Schema.MAP,
147
schema=output_schema)
151
attributes_schema = {
152
CONFIG_ATTR: attributes.Schema(
153
_("The config value of the software config.")
157
def handle_create(self):
158
props = dict(self.properties)
159
props[self.NAME] = self.physical_resource_name()
161
sc = self.rpc_client().create_software_config(self.context, **props)
162
self.resource_id_set(sc[rpc_api.SOFTWARE_CONFIG_ID])
164
def handle_delete(self):
166
if self.resource_id is None:
170
self.rpc_client().delete_software_config(
171
self.context, self.resource_id)
172
except Exception as ex:
173
self.rpc_client().ignore_error_named(ex, 'NotFound')
175
def _resolve_attribute(self, name):
177
"config" returns the config value of the software config. If the
178
software config does not exist, returns an empty string.
180
if name == self.CONFIG_ATTR and self.resource_id:
182
sc = self.rpc_client().show_software_config(
183
self.context, self.resource_id)
184
return sc[rpc_api.SOFTWARE_CONFIG_CONFIG]
185
except Exception as ex:
186
self.rpc_client().ignore_error_named(ex, 'NotFound')
189
def resource_mapping():
191
'OS::Heat::SoftwareConfig': SoftwareConfig,