-
Notifications
You must be signed in to change notification settings - Fork 760
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use resource types for parameter validation #9229
Comments
One thing to keep in mind with provider-supplied types is that the compiler doesn't trust that they are completely accurate (or that they will remain completely accurate during the period between when the template is compiled and when it is deployed). Type checking based on resource types will generate warnings accompanied by links to report type inaccuracies, while type checking based on something defined within the template itself will generate errors. Consequently, param accessPolicy = typeof(resource 'Microsoft.KeyVault/vaults@2022-07-01#/properties/accessPolicies/*') might compile to: {
"parameters": {
"accessPolicy": {
"type": "object",
"metadata": {
"__bicep_resource_type": "Microsoft.KeyVault/vaults@2022-07-01#/properties/accessPolicies/*"
}
}
}
} Some open questions with this approach:
|
On first reading, this looks like it is simply a way of allowing people to declare a variable's type based on an existing type. For example, following the example in there, I can see that if it was in place, then rather than writing...
...then I could declare...
So we've replaced the direct reference to a However, I've been referred here from #9797 by @jeskew, with the implication that this has an additional behaviour, which I didn't "get" this from reading the proposal, so I wanted to check... @jeskew are you proposing that: When declaring a parameter by using a reference to a property, the declaration is saying that not only the type of that property would come across to this declaration; but any validation decorators applied to that property would come too. So for example, if the Service Bus |
Yes that's right. Can you clarify why you would not want that? IOW, what are you looking to enable with this |
I didn't say that I didn't want it, I was just surprised :) ... I've used plenty of languages over the years, and I don't recall seeing something like this before (a type declaration which includes specific validation logic); but that doesn't mean it isn't a good idea. I'm guessing that it probably infers all of the decorators, because there is probably no way to distinguish the validator decorators from the others; and that's probably fine, too. The derived declaration may want to override some of them, like There might need to be a way to prevent something coming across, although I'm not experienced enough with Bicep to give an example... perhaps the |
To me and our large insurance company's usage even just a typehint to the language server would already help immensely. Currently all var objects are typeless basically, and telling the lang server something simple, that this is indeed a |
Based on a team discussion, the initial implementation will use a slightly different syntax from the proposal described above. Instead of a |
Partially address #9229 This PR adds a new ambient type symbol name `resource` (in the `sys` namespace) and kind of syntax for using types that accept parameters (`resource<'type@version'>`). This new kind of syntax is called a `ParameterizedTypeInstantiation` node because, following C#'s example, each appearance of the syntax is expected to produce a type symbol and an IR expression that can be used in place of a concrete type clause. This PR does **not** implement the logic to use the type of a specific property within a resource body, as that is turning out to be fairly complex, and this PR is already large and pretty dense. ###### Microsoft Reviewers: [Open in CodeFlow](https://microsoft.github.io/open-pr/?codeflow=https://github.com/Azure/bicep/pull/12591) --------- Co-authored-by: Anthony Martin <[email protected]>
Resolves #12920 Resolves #9229 This PR allows elements or properties of types to be used as standalone type expressions. This feature is compatible with both resource-derived types and compile-time imports, as shown in the following example: types.bicep ```bicep @export() type myObject = { quux: int saSku: resource<'Microsoft.Storage/storageAccounts@2022-09-01'>.sku } ``` main.bicep ```bicep import * as types from 'types.bicep' type test = { baz: types.myObject } type test2 = { foo: { bar: test } } type test3 = test2.foo.bar.baz.quux // ^^ compiles to {"$ref": "#/definitions/_1.myObject/properties/quux"} type test4 = test2.foo.bar.baz.saSku.name // ^^ compiles to: // { // "type": "string", // "metadata": { // "__bicep_resource_derived_type!": "Microsoft.Storage/storageAccounts@2022-09-01#properties/sku/properties/name" // } // } ``` Accessing the following element kinds is supported: * Properties may be dereferenced via dot notation * Tuple items may be dereferenced via array index * An object's additional properties type declaration may be dereferenced via a special `.*` syntax * A typed array's element type declaration may be dereferenced via a special `[*]` syntax For example: ```bicep type anObject = { property: int *: string } type strings = string[] type tuple = [int, string] param propertyDeref anObject.property = 10 // type compiles to {"$ref": "#/definitions/anObject/properties/property"} param additionalPropertiesDeref anObject.* = 'foo' // type compiles to {"$ref": "#/definitions/anObject/additionalProperties"} param elementDeref strings[*] = 'bar' // type compiles to {"$ref": "#/definitions/strings/items"} param itemDeref tuple[1] = 'baz' // type compiles to {"$ref": "#/definitions/tuple/prefixItems/1"} ``` CodeFlow](https://microsoft.github.io/open-pr/?codeflow=https://github.com/Azure/bicep/pull/13047)
Is your feature request related to a problem? Please describe.
With the user-defined types preview enabled, users can declare custom types and validate that parameters match those type declarations. If a parameter value is passed directly to a
resource
as a property, however, users need to re-declare the existing type definition as type symbols within their template (or forgo validation).Describe the solution you'd like
It should be possible to use an existing resource type (or portion thereof) from a built-in or imported namespace. This could be accomplished via
typeof
function or keyword, such as intypeof('Microsoft.KeyVault/vaults@2022-07-01#properties.accessPolicies[*]')
.If we want to leave room for a similar function that gets the assigned type of a variable or parameter, we might need two functions or to require the
resource
keyword:The text was updated successfully, but these errors were encountered: