-
Notifications
You must be signed in to change notification settings - Fork 20
/
data-types.yaml
294 lines (244 loc) · 8.32 KB
/
data-types.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
tosca_definitions_version: tosca_simple_yaml_1_3
# To apply the constraints use "--coerce":
# puccini-tosca compile --coerce examples/1.3/data-types.yaml
metadata:
template_name: Data Types Example
template_author: Puccini
node_types:
DataNode:
properties:
# Primitive types
string:
type: string
integer:
type: integer
float:
type: float
default: -0.1
boolean:
type: boolean
required: false
# Note: We must wrap "null" in quotes so that the YAML parser won't treat it as null
'null':
type: 'null'
# List and map types *must* specify "entry_schema" for entry types
integer_list:
type: list
entry_schema: integer
string_map:
type: map
entry_schema: string
# Complex types are defined in "data_types"
complex:
type: Complex
# The "entry_schema" can be a complex type
complex_list:
type: list
entry_schema: Complex
# The following are "special" types
# Puccini will insert an object that has a rich API, accessible in JavaScript
scalar_unit_size:
type: scalar-unit.size
scalar_unit_time:
type: scalar-unit.time
scalar_unit_frequency:
type: scalar-unit.frequency
scalar_unit_bitrate:
type: scalar-unit.bitrate
timestamp:
type: timestamp
version:
type: version
range:
type: range
# These can also be considered to be "special" types
# Though they are currently part of the Simple Profile
json:
type: tosca.datatypes.json
xml:
type: tosca.datatypes.xml
# Properties can have constraints
# Note that constraints *must* use literal values (no function calls)
# (*All* constraints must be satisfied by values; it's a logical "and")
constrained_string:
type: string
constraints:
- min_length: 2
- max_length: 5
# This property is also constrained, but not here: see the data type
# (You can also add *additional* constraints here if needed; it's logical "and")
lowercase:
type: LowerCase
# We can constrain map keys via the "key_schema"
# The key_schema must be string (the default) or a derivative
lowercase_string_map:
type: map
key_schema: LowerCase
entry_schema: string
# Using a longer notation you can also set constraints for the entry schema
# (Remember: logical "and")
constrained_float_list:
type: list
entry_schema:
type: float
constraints:
- in_range: [ -1.0, 1.0 ]
# Constraints are type-aware, such that comparisons of special type values
# will be done semantically, e.g. a "scalar-unit":
constrained_time:
type: scalar-unit.time
constraints:
- in_range: [ 1m, 1h ]
# Another example showing semantic "version" comparison
constrained_version:
type: version
constraints:
- in_range: [ 1.2.3.beta-3, 1.2.3.beta-5 ]
# Custom map
time_map:
type: TimeMap
# In Puccini you can also create your own custom constraints
# See: examples/javascript/constraints.yaml
data_types:
Complex:
# (Poorly named: these are really "fields" of our complex type, rather than "properties")
properties:
string:
type: string
# Individual "properties" can have default values
default: Default Value
integer:
type: integer
float:
type: float
# "Properties" are required by default
required: false
# Complex types can be nested
nested:
type: Nested
Nested:
properties:
nested_float:
type: float
constraints:
- greater_or_equal: 0.0
nested_string:
type: string
required: false
# Puccini lets you derive from primitive types; useful for adding constraints
# Note that if you derive from a primitive you *cannot* also define properties
LowerCase:
derived_from: string
description: Lowercase string
constraints:
- pattern: '[a-z]*'
TimeMap:
derived_from: map
# You can only use entry_schema if you derive from map or list
# And you can only use key_schema if you derive from map
entry_schema: scalar-unit.time
topology_template:
inputs:
number:
type: integer
default: 4
node_templates:
data:
type: DataNode
properties:
string: Hello, Puccini
integer: 123
float: 12.3
boolean: true
# The "null" type can have only the null value
'null': null
integer_list: [ 1, 2, 3, { get_input: number } ]
string_map:
Greeting: Hello
# Note that values as well map keys could be function calls
Message: { concat: [ Good, ' ', Day ] }
{ concat: [ Recip, ient ] }: Puccini
lowercase_string_map:
greeting: Hello
{ concat: [ recip, ient ] }: Puccini
complex:
string: Hello, Puccini
integer: 123
nested:
nested_float: 12.3
complex_list:
- integer: 123
nested:
nested_float: 45.6
- integer: 789
nested:
nested_float: 1.0
# Size is normalized to number of bytes (unsigned integer)
# GiB, MiB, etc. are also supported for multiples of 1024
# For most scalars the case of the unit doesn't matter ("gB" = "Gb")
scalar_unit_size: 1.23 gb
# Time is normalized to seconds (float)
# Also, you don't need a space between the scalar and the unit
scalar_unit_time: 1.23ms
# Frequency is normalized to Hz (float)
scalar_unit_frequency: 123e3 kHz
# Bitrate is normalized to bits-per-second (float)
# This is the only scalar in which the case *does* matter:
# Use "b" for bits and "B" for bytes
# Gibps, Mibps, etc. are also supported for multiples of 1024
scalar_unit_bitrate: 1.23 KiBps
# "timestamp" is a string formatted according to ISO 8601:
timestamp: '1975-09-15 12:34:56.7 +2'
# Note that some YAML environments may support a !!timestamp type:
# http://yaml.org/type/timestamp.html
# Normally Puccini will not allow it, but it could be enabled via a quirk:
# puccini-tosca compile --quirk=data_types.timestamp.permissive
# (In this case the YAML parser parses the timestamp, not Puccini's TOSCA parser)
#timestamp: !!timestamp 1975-09-15t12:34:56.7+02:00
# The version structure in TOSCA is very specific and might not fit your needs
# This example has all fields: major.minor.fix.qualifier-build
# (You need *at least* major.minor)
# With "--quirk=data_types.string.permissive" enabled Puccini will also accept
# literal integers such as "5" and literal floats such as "5.2"
version: 1.2.3.beta-4
# Range is actually quite limited in use:
# * Unsigned integers only
# * Upper must be >= than lower
# You can also use "UNBOUNDED" string for the upper bound, which will be converted to
# the maximum uint value
range: [ 1, UNBOUNDED ]
# These are validated, but otherwise the text will be left as is
json: |-
{
"key1": "value",
"key2": [ 1, 2, 3 ]
}
xml:
# Constraints are applied *after* functions are called
concat:
- |
<tag1>value</tag1>
<tag2>
<entry>1</entry>
<entry>2</entry>
<entry>3</entry>
- |-
</tag2>
# Constraints: min length = 2 and max length = 5
# (The length-related constraints work on both strings and lists)
constrained_string: ABCDE
# Constraints: lowercase letters only
lowercase: helloworld
# Constraints: -1.0 <= x <= 1.0
constrained_float_list:
- -0.999
- 0.0
- 1.0
# Constraints: 1m <= x <= 1h
constrained_time: 10.5m
# Constraints: 1.2.3.beta-3 <= x <= 1.2.3.beta-5
constrained_version: 1.2.3.beta-4
# Custom map
time_map:
first: 100 s
second: 200 s