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