github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/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 // buf:lint:ignore FIELD_LOWER_SNAKE_CASE 64 Attr Attr = 3; 65 Block block_value = 4; 66 BlockAttrs block_attrs = 5; 67 BlockList block_list = 6; 68 BlockSet block_set = 7; 69 BlockMap block_map = 8; 70 Default default = 9; 71 Literal literal = 10; 72 } 73 } 74 75 /* Attr spec type reads the value of an attribute in the current body 76 and returns that value as its result. It also creates validation constraints 77 for the given attribute name and its value. 78 79 ```hcl 80 Attr { 81 name = "document_root" 82 type = string 83 required = true 84 } 85 ``` 86 87 `Attr` spec blocks accept the following arguments: 88 89 * `name` (required) - The attribute name to expect within the HCL input file. 90 This may be omitted when a default name selector is created by a parent 91 `Object` spec, if the input attribute name should match the output JSON 92 object property name. 93 94 * `type` (optional) - A [type expression](#type-expressions) that the given 95 attribute value must conform to. If this argument is set, `hcldec` will 96 automatically convert the given input value to this type or produce an 97 error if that is not possible. 98 99 * `required` (optional) - If set to `true`, `hcldec` will produce an error 100 if a value is not provided for the source attribute. 101 102 `Attr` is a leaf spec type, so no nested spec blocks are permitted. 103 */ 104 message Attr { 105 string name = 1; 106 string type = 2; 107 bool required = 3; 108 } 109 110 /* Block spec type applies one nested spec block to the contents of a 111 block within the current body and returns the result of that spec. It also 112 creates validation constraints for the given block type name. 113 114 ```hcl 115 Block { 116 name = "logging" 117 118 Object { 119 Attr "level" { 120 type = string 121 } 122 Attr "file" { 123 type = string 124 } 125 } 126 } 127 ``` 128 129 `Block` spec blocks accept the following arguments: 130 131 * `name` (required) - The block type name to expect within the HCL 132 input file. This may be omitted when a default name selector is created 133 by a parent `Object` spec, if the input block type name should match the 134 output JSON object property name. 135 136 * `required` (optional) - If set to `true`, `hcldec` will produce an error 137 if a block of the specified type is not present in the current body. 138 139 `Block` creates a validation constraint that there must be zero or one blocks 140 of the given type name, or exactly one if `required` is set. 141 142 `Block` expects a single nested spec block, which is applied to the body of 143 the block of the given type when it is present. 144 145 */ 146 message Block { 147 string name = 1; 148 bool required = 2; 149 Spec nested = 3; 150 } 151 152 /* 153 The BlockAttrs spec type is similar to an Attr spec block of a map type, 154 but it produces a map from the attributes of a block rather than from an 155 attribute's expression. 156 157 ```hcl 158 BlockAttrs { 159 name = "variables" 160 type = string 161 required = false 162 } 163 ``` 164 165 This allows a map with user-defined keys to be produced within block syntax, 166 but due to the constraints of that syntax it also means that the user will 167 be unable to dynamically-generate either individual key names using key 168 expressions or the entire map value using a `for` expression. 169 170 `BlockAttrs` spec blocks accept the following arguments: 171 172 * `name` (required) - The block type name to expect within the HCL 173 input file. This may be omitted when a default name selector is created 174 by a parent `object` spec, if the input block type name should match the 175 output JSON object property name. 176 177 * `type` (required) - The value type to require for each of the 178 attributes within a matched block. The resulting value will be a JSON 179 object whose property values are of this type. 180 181 * `required` (optional) - If `true`, an error will be produced if a block 182 of the given type is not present. If `false` -- the default -- an absent 183 block will be indicated by producing `null`. 184 */ 185 message BlockAttrs { 186 string name = 1; 187 string type = 2; 188 bool required = 3; 189 } 190 191 /* BlockList spec type is similar to `Block`, but it accepts zero or 192 more blocks of a specified type rather than requiring zero or one. The 193 result is a JSON array with one entry per block of the given type. 194 195 ```hcl 196 BlockList { 197 name = "log_file" 198 199 Object { 200 Attr "level" { 201 type = string 202 } 203 Attr "filename" { 204 type = string 205 required = true 206 } 207 } 208 } 209 ``` 210 211 `BlockList` spec blocks accept the following arguments: 212 213 * `name` (required) - The block type name to expect within the HCL 214 input file. This may be omitted when a default name selector is created 215 by a parent `Object` spec, if the input block type name should match the 216 output JSON object property name. 217 218 * `min_items` (optional) - If set to a number greater than zero, `hcldec` will 219 produce an error if fewer than the given number of blocks are present. 220 221 * `max_items` (optional) - If set to a number greater than zero, `hcldec` will 222 produce an error if more than the given number of blocks are present. This 223 attribute must be greater than or equal to `min_items` if both are set. 224 225 `Block` creates a validation constraint on the number of blocks of the given 226 type that must be present. 227 228 `Block` expects a single nested spec block, which is applied to the body of 229 each matching block to produce the resulting list items. 230 231 */ 232 message BlockList { 233 string name = 1; 234 uint64 min_items = 2; 235 uint64 max_items = 3; 236 Spec nested = 4; 237 } 238 239 /* BlockSet spec type behaves the same as BlockList except that 240 the result is in no specific order and any duplicate items are removed. 241 242 ```hcl 243 BlockSet { 244 name = "log_file" 245 246 Object { 247 Attr "level" { 248 type = string 249 } 250 Attr "filename" { 251 type = string 252 required = true 253 } 254 } 255 } 256 ``` 257 258 The contents of `BlockSet` are the same as for `BlockList`. 259 260 */ 261 message BlockSet { 262 string name = 1; 263 uint64 min_items = 2; 264 uint64 max_items = 3; 265 Spec nested = 4; 266 } 267 268 /* BlockMap spec type is similar to `Block`, but it accepts zero or 269 more blocks of a specified type rather than requiring zero or one. The 270 result is a JSON object, or possibly multiple nested JSON objects, whose 271 properties are derived from the labels set on each matching block. 272 273 ```hcl 274 BlockMap { 275 name = "log_file" 276 labels = ["filename"] 277 278 Object { 279 Attr "level" { 280 type = string 281 required = true 282 } 283 } 284 } 285 ``` 286 287 `BlockMap` spec blocks accept the following arguments: 288 289 * `name` (required) - The block type name to expect within the HCL 290 input file. This may be omitted when a default name selector is created 291 by a parent `Object` spec, if the input block type name should match the 292 output JSON object property name. 293 294 * `labels` (required) - A list of user-oriented block label names. Each entry 295 in this list creates one level of object within the output value, and 296 requires one additional block header label on any child block of this type. 297 Block header labels are the quoted strings that appear after the block type 298 name but before the opening `{`. 299 300 `Block` creates a validation constraint on the number of labels that blocks 301 of the given type must have. 302 303 `Block` expects a single nested spec block, which is applied to the body of 304 each matching block to produce the resulting map items. 305 306 */ 307 message BlockMap { 308 string name = 1; 309 repeated string labels = 2; 310 Spec nested = 3; 311 } 312 313 /* Literal spec type returns a given literal value, and creates no 314 validation constraints. It is most commonly used with the `Default` spec 315 type to create a fallback value, but can also be used e.g. to fill out 316 required properties in an `Object` spec that do not correspond to any 317 construct in the input configuration. 318 319 ```hcl 320 Literal { 321 value = "hello world" 322 } 323 ``` 324 325 `Literal` spec blocks accept the following argument: 326 327 * `value` (required) - The value to return. This attribute may be an expression 328 that uses [functions](#spec-definition-functions). 329 330 `Literal` is a leaf spec type, so no nested spec blocks are permitted. 331 */ 332 message Literal { 333 string value = 1; 334 } 335 336 /* Default spec type evaluates a sequence of nested specs in turn and 337 returns the result of the first one that produces a non-null value. 338 It creates no validation constraints of its own, but passes on the validation 339 constraints from its first nested block. 340 341 ```hcl 342 Default { 343 Attr { 344 name = "private" 345 type = bool 346 } 347 Literal { 348 value = false 349 } 350 } 351 ``` 352 353 A `Default` spec block must have at least one nested spec block, and should 354 generally have at least two since otherwise the `Default` wrapper is a no-op. 355 356 The second and any subsequent spec blocks are _fallback_ specs. These exhibit 357 their usual behavior but are not able to impose validation constraints on the 358 current body since they are not evaluated unless all prior specs produce 359 `null` as their result. 360 361 */ 362 message Default { 363 Spec primary = 1; 364 Spec default = 2; 365 } 366 367 /* Object spec type is the most commonly used at the root of a spec file. 368 Its result is a JSON object whose properties are set based on any nested 369 spec blocks: 370 371 ```hcl 372 Object { 373 Attr "name" { 374 type = "string" 375 } 376 Block "address" { 377 Object { 378 Attr "street" { 379 type = "string" 380 } 381 # ... 382 } 383 } 384 } 385 ``` 386 387 Nested spec blocks inside `Object` must always have an extra block label 388 `"name"`, `"address"` and `"street"` in the above example) that specifies 389 the name of the property that should be created in the JSON object result. 390 This label also acts as a default name selector for the nested spec, allowing 391 the `Attr` blocks in the above example to omit the usually-required `name` 392 argument in cases where the HCL input name and JSON output name are the same. 393 394 An `Object` spec block creates no validation constraints, but it passes on 395 any validation constraints created by the nested specs. 396 */ 397 message Object { 398 map<string, Spec> attributes = 1; 399 } 400 401 /* Array spec type produces a JSON array whose elements are set based on 402 any nested spec blocks: 403 404 ```hcl 405 Array { 406 Attr { 407 name = "first_element" 408 type = "string" 409 } 410 Attr { 411 name = "second_element" 412 type = "string" 413 } 414 } 415 ``` 416 417 An `Array` spec block creates no validation constraints, but it passes on 418 any validation constraints created by the nested specs. 419 */ 420 message Array { 421 repeated Spec values = 1; 422 }