github.com/ferranbt/nomad@v0.9.3-0.20190607002617-85c449b7667c/plugins/shared/hclspec/hcl_spec.proto (about) 1 syntax = "proto3"; 2 3 option go_package = "hclspec"; 4 5 /* Spec allows exposing the specification for an HCL body, allowing for parsing and 6 validation. 7 8 Certain expressions within a specification may use the following functions. 9 The documentation for each spec type above specifies where functions may 10 be used. 11 12 * `abs(number)` returns the absolute (positive) value of the given number. 13 * `coalesce(vals...)` returns the first non-null value given. 14 * `concat(lists...)` concatenates together all of the given lists to produce a new list. 15 * `hasindex(val, idx)` returns true if the expression `val[idx]` could succeed. 16 * `int(number)` returns the integer portion of the given number, rounding towards zero. 17 * `jsondecode(str)` interprets the given string as JSON and returns the resulting data structure. 18 * `jsonencode(val)` returns a JSON-serialized version of the given value. 19 * `length(collection)` returns the number of elements in the given collection (list, set, map, object, or tuple). 20 * `lower(string)` returns the given string with all uppercase letters converted to lowercase. 21 * `max(numbers...)` returns the greatest of the given numbers. 22 * `min(numbers...)` returns the smallest of the given numbers. 23 * `reverse(string)` returns the given string with all of the characters in reverse order. 24 * `strlen(string)` returns the number of characters in the given string. 25 * `substr(string, offset, length)` returns the requested substring of the given string. 26 * `upper(string)` returns the given string with all lowercase letters converted to uppercase. 27 28 ## Type Expressions 29 30 Type expressions are used to describe the expected type of an attribute, as 31 an additional validation constraint. 32 33 A type expression uses primitive type names and compound type constructors. 34 A type constructor builds a new type based on one or more type expression 35 arguments. 36 37 The following type names and type constructors are supported: 38 39 * `any` is a wildcard that accepts a value of any type. (In HCL terms, this 40 is the _dynamic pseudo-type_.) 41 * `string` is a Unicode string. 42 * `number` is an arbitrary-precision floating point number. 43 * `bool` is a boolean value (`true` or `false`) 44 * `list(element_type)` constructs a list type with the given element type 45 * `set(element_type)` constructs a set type with the given element type 46 * `map(element_type)` constructs a map type with the given element type 47 * `object({name1 = element_type, name2 = element_type, ...})` constructs 48 an object type with the given attribute types. 49 * `tuple([element_type, element_type, ...])` constructs a tuple type with 50 the given element types. This can be used, for example, to require an 51 array with a particular number of elements, or with elements of different 52 types. 53 54 `null` is a valid value of any type, and not a type itself. 55 */ 56 package hashicorp.nomad.plugins.shared.hclspec; 57 58 // Spec defines the available specification types. 59 message Spec { 60 oneof block { 61 Object object = 1; 62 Array array = 2; 63 Attr Attr = 3; 64 Block block_value = 4; 65 BlockAttrs block_attrs = 5; 66 BlockList block_list = 6; 67 BlockSet block_set = 7; 68 BlockMap block_map = 8; 69 Default default = 9; 70 Literal literal = 10; 71 } 72 } 73 74 /* Attr spec type reads the value of an attribute in the current body 75 and returns that value as its result. It also creates validation constraints 76 for the given attribute name and its value. 77 78 ```hcl 79 Attr { 80 name = "document_root" 81 type = string 82 required = true 83 } 84 ``` 85 86 `Attr` spec blocks accept the following arguments: 87 88 * `name` (required) - The attribute name to expect within the HCL input file. 89 This may be omitted when a default name selector is created by a parent 90 `Object` spec, if the input attribute name should match the output JSON 91 object property name. 92 93 * `type` (optional) - A [type expression](#type-expressions) that the given 94 attribute value must conform to. If this argument is set, `hcldec` will 95 automatically convert the given input value to this type or produce an 96 error if that is not possible. 97 98 * `required` (optional) - If set to `true`, `hcldec` will produce an error 99 if a value is not provided for the source attribute. 100 101 `Attr` is a leaf spec type, so no nested spec blocks are permitted. 102 */ 103 message Attr { 104 string name = 1; 105 string type = 2; 106 bool required = 3; 107 } 108 109 /* Block spec type applies one nested spec block to the contents of a 110 block within the current body and returns the result of that spec. It also 111 creates validation constraints for the given block type name. 112 113 ```hcl 114 Block { 115 name = "logging" 116 117 Object { 118 Attr "level" { 119 type = string 120 } 121 Attr "file" { 122 type = string 123 } 124 } 125 } 126 ``` 127 128 `Block` spec blocks accept the following arguments: 129 130 * `name` (required) - The block type name to expect within the HCL 131 input file. This may be omitted when a default name selector is created 132 by a parent `Object` spec, if the input block type name should match the 133 output JSON object property name. 134 135 * `required` (optional) - If set to `true`, `hcldec` will produce an error 136 if a block of the specified type is not present in the current body. 137 138 `Block` creates a validation constraint that there must be zero or one blocks 139 of the given type name, or exactly one if `required` is set. 140 141 `Block` expects a single nested spec block, which is applied to the body of 142 the block of the given type when it is present. 143 144 */ 145 message Block { 146 string name = 1; 147 bool required = 2; 148 Spec nested = 3; 149 } 150 151 /* 152 The BlockAttrs spec type is similar to an Attr spec block of a map type, 153 but it produces a map from the attributes of a block rather than from an 154 attribute's expression. 155 156 ```hcl 157 BlockAttrs { 158 name = "variables" 159 type = string 160 required = false 161 } 162 ``` 163 164 This allows a map with user-defined keys to be produced within block syntax, 165 but due to the constraints of that syntax it also means that the user will 166 be unable to dynamically-generate either individual key names using key 167 expressions or the entire map value using a `for` expression. 168 169 `BlockAttrs` spec blocks accept the following arguments: 170 171 * `name` (required) - The block type name to expect within the HCL 172 input file. This may be omitted when a default name selector is created 173 by a parent `object` spec, if the input block type name should match the 174 output JSON object property name. 175 176 * `type` (required) - The value type to require for each of the 177 attributes within a matched block. The resulting value will be a JSON 178 object whose property values are of this type. 179 180 * `required` (optional) - If `true`, an error will be produced if a block 181 of the given type is not present. If `false` -- the default -- an absent 182 block will be indicated by producing `null`. 183 */ 184 message BlockAttrs { 185 string name = 1; 186 string type = 2; 187 bool required = 3; 188 } 189 190 /* BlockList spec type is similar to `Block`, but it accepts zero or 191 more blocks of a specified type rather than requiring zero or one. The 192 result is a JSON array with one entry per block of the given type. 193 194 ```hcl 195 BlockList { 196 name = "log_file" 197 198 Object { 199 Attr "level" { 200 type = string 201 } 202 Attr "filename" { 203 type = string 204 required = true 205 } 206 } 207 } 208 ``` 209 210 `BlockList` spec blocks accept the following arguments: 211 212 * `name` (required) - The block type name to expect within the HCL 213 input file. This may be omitted when a default name selector is created 214 by a parent `Object` spec, if the input block type name should match the 215 output JSON object property name. 216 217 * `min_items` (optional) - If set to a number greater than zero, `hcldec` will 218 produce an error if fewer than the given number of blocks are present. 219 220 * `max_items` (optional) - If set to a number greater than zero, `hcldec` will 221 produce an error if more than the given number of blocks are present. This 222 attribute must be greater than or equal to `min_items` if both are set. 223 224 `Block` creates a validation constraint on the number of blocks of the given 225 type that must be present. 226 227 `Block` expects a single nested spec block, which is applied to the body of 228 each matching block to produce the resulting list items. 229 230 */ 231 message BlockList { 232 string name = 1; 233 uint64 min_items = 2; 234 uint64 max_items = 3; 235 Spec nested = 4; 236 } 237 238 /* BlockSet spec type behaves the same as BlockList except that 239 the result is in no specific order and any duplicate items are removed. 240 241 ```hcl 242 BlockSet { 243 name = "log_file" 244 245 Object { 246 Attr "level" { 247 type = string 248 } 249 Attr "filename" { 250 type = string 251 required = true 252 } 253 } 254 } 255 ``` 256 257 The contents of `BlockSet` are the same as for `BlockList`. 258 259 */ 260 message BlockSet { 261 string name = 1; 262 uint64 min_items = 2; 263 uint64 max_items = 3; 264 Spec nested = 4; 265 } 266 267 /* BlockMap spec type is similar to `Block`, but it accepts zero or 268 more blocks of a specified type rather than requiring zero or one. The 269 result is a JSON object, or possibly multiple nested JSON objects, whose 270 properties are derived from the labels set on each matching block. 271 272 ```hcl 273 BlockMap { 274 name = "log_file" 275 labels = ["filename"] 276 277 Object { 278 Attr "level" { 279 type = string 280 required = true 281 } 282 } 283 } 284 ``` 285 286 `BlockMap` spec blocks accept the following arguments: 287 288 * `name` (required) - The block type name to expect within the HCL 289 input file. This may be omitted when a default name selector is created 290 by a parent `Object` spec, if the input block type name should match the 291 output JSON object property name. 292 293 * `labels` (required) - A list of user-oriented block label names. Each entry 294 in this list creates one level of object within the output value, and 295 requires one additional block header label on any child block of this type. 296 Block header labels are the quoted strings that appear after the block type 297 name but before the opening `{`. 298 299 `Block` creates a validation constraint on the number of labels that blocks 300 of the given type must have. 301 302 `Block` expects a single nested spec block, which is applied to the body of 303 each matching block to produce the resulting map items. 304 305 */ 306 message BlockMap { 307 string name = 1; 308 repeated string labels = 2; 309 Spec nested = 3; 310 } 311 312 /* Literal spec type returns a given literal value, and creates no 313 validation constraints. It is most commonly used with the `Default` spec 314 type to create a fallback value, but can also be used e.g. to fill out 315 required properties in an `Object` spec that do not correspond to any 316 construct in the input configuration. 317 318 ```hcl 319 Literal { 320 value = "hello world" 321 } 322 ``` 323 324 `Literal` spec blocks accept the following argument: 325 326 * `value` (required) - The value to return. This attribute may be an expression 327 that uses [functions](#spec-definition-functions). 328 329 `Literal` is a leaf spec type, so no nested spec blocks are permitted. 330 */ 331 message Literal { 332 string value = 1; 333 } 334 335 /* Default spec type evaluates a sequence of nested specs in turn and 336 returns the result of the first one that produces a non-null value. 337 It creates no validation constraints of its own, but passes on the validation 338 constraints from its first nested block. 339 340 ```hcl 341 Default { 342 Attr { 343 name = "private" 344 type = bool 345 } 346 Literal { 347 value = false 348 } 349 } 350 ``` 351 352 A `Default` spec block must have at least one nested spec block, and should 353 generally have at least two since otherwise the `Default` wrapper is a no-op. 354 355 The second and any subsequent spec blocks are _fallback_ specs. These exhibit 356 their usual behavior but are not able to impose validation constraints on the 357 current body since they are not evaluated unless all prior specs produce 358 `null` as their result. 359 360 */ 361 message Default { 362 Spec primary = 1; 363 Spec default = 2; 364 } 365 366 /* Object spec type is the most commonly used at the root of a spec file. 367 Its result is a JSON object whose properties are set based on any nested 368 spec blocks: 369 370 ```hcl 371 Object { 372 Attr "name" { 373 type = "string" 374 } 375 Block "address" { 376 Object { 377 Attr "street" { 378 type = "string" 379 } 380 # ... 381 } 382 } 383 } 384 ``` 385 386 Nested spec blocks inside `Object` must always have an extra block label 387 `"name"`, `"address"` and `"street"` in the above example) that specifies 388 the name of the property that should be created in the JSON object result. 389 This label also acts as a default name selector for the nested spec, allowing 390 the `Attr` blocks in the above example to omit the usually-required `name` 391 argument in cases where the HCL input name and JSON output name are the same. 392 393 An `Object` spec block creates no validation constraints, but it passes on 394 any validation constraints created by the nested specs. 395 */ 396 message Object { 397 map<string, Spec> attributes = 1; 398 } 399 400 /* Array spec type produces a JSON array whose elements are set based on 401 any nested spec blocks: 402 403 ```hcl 404 Array { 405 Attr { 406 name = "first_element" 407 type = "string" 408 } 409 Attr { 410 name = "second_element" 411 type = "string" 412 } 413 } 414 ``` 415 416 An `Array` spec block creates no validation constraints, but it passes on 417 any validation constraints created by the nested specs. 418 */ 419 message Array { 420 repeated Spec values = 1; 421 }