**Edit: I thought I'd tried this before posting, but I guess not - the solution was:
"listPublishingUsername": {
"value": "[list(resourceId('Microsoft.Web/sites/config', variables('websiteName'), 'publishingcredentials'), '2016-08-01').properties.publishingUserName]",
"type": "string"
},
"listPublishingPassword": {
"value": "[list(resourceId('Microsoft.Web/sites/config', variables('websiteName'), 'publishingcredentials'), '2016-08-01').properties.publishingPassword]",
"type": "string"
}
I'm trying to get the publishingUsername/publishingPassword nested values from an Azure JSON deployment.
With:
"outputs": {
"listPublishingCredentials": {
"value": "[list(resourceId('Microsoft.Web/sites/config', parameters('sites_testdsfsdfsfsfs_name'), 'publishingcredentials'), '2014-06-01')]",
"type": "object"
I'm able to get all values that I can see in the resource portal
if I suffix it with .parameters I'm able to get down a level to just the parameters, however if I try parameters.publishingPassword (which would be the nested value based on the resource view) it returns an error
"code": "DeploymentOutputEvaluationFailed",
"target": "listPublishingCredentials",
"message": "The template output 'listPublishingCredentials' is not valid: Index (zero based) must be greater than or equal to zero and less than the size of the argument list..""
Alternatively is there any documentation that explains what parameters/syntax is valid for resources like Microsoft.Web/sites/config?
edit:
"outputs": {
"listPublishingCredentials": {
"value": "[list(resourceId('Microsoft.Web/sites/config', parameters('sites_testdsfsdfsfsfs_name'), 'publishingcredentials'), '2016-08-01').properties]",
"type": "object"
}
works
"outputs": {
"listPublishingCredentials": {
"value": "[list(resourceId('Microsoft.Web/sites/config', parameters('sites_testdsfsdfsfsfs_name'), 'publishingcredentials'), '2016-08-01').properties.publishingPassword]",
"type": "object"
}
doesn't
"listPublishingUsername": {
"value": "[list(resourceId('Microsoft.Web/sites/config', variables('websiteName'), 'publishingcredentials'), '2016-08-01').properties.publishingUserName]",
"type": "string"
},
"listPublishingPassword": {
"value": "[list(resourceId('Microsoft.Web/sites/config', variables('websiteName'), 'publishingcredentials'), '2016-08-01').properties.publishingPassword]",
"type": "string"
}
Related
I'm trying to create a JSON schema to validate YAML for some VSCode intellisense. What I'm trying to do is choose the correct subschema to use for a property in the main schema based on an adjacent key's value.
Some JSON examples:
[
{
"name": "doesntmatter",
"matchMe": "stringToMatch:123whatever",
"mergeMe": {
"key1": "value1",
"key2": "value2"
}
}
]
[
{
"name": "doesntmatter",
"matchMe": "anotherStringToMatch:123whatever",
"mergeMe": {
"anotherKey": "valueSomething",
"anotherKey2": "cheese"
}
}
]
So I need to choose the correct schemas for the mergeMe objects based on the substring match of matchMe. After following a bunch of answers, I'm at a point where I can either make it match multiple, and error my linter, or match none, but an online validator says it's ok (except nothing matches as the required fields aren't triggering).
I moved my sub-schemas to be merged into definitions to reference them, and then used an if/then to match. That worked with one, but then I tried to expand it to do the tree matching, and I can't get that to work. Someone said that I should wrap my if/thens in an allOf (I'm not sure why that would work since surely not all of them would match?). Changing it to an anyOf makes none of them match and I get no intellisense. Nor do I really understand why I should wrap single if/thens or thens in allOfs.
The idea is that based on the pattern it uses a definitions schema to match the mergeMe property, but the conditional logic isn't quite right. Thinned schema below:
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/example.json",
"type": "array",
"title": "The root schema",
"description": "The root schema comprises the entire JSON document.",
"default": [],
"additionalItems": true,
"definitions": {
"stringToMatch": {
"$id": "#/definitions/stringToMatch",
"type": "object",
"properties": {
"key1": {
"type": "string"
}
},
"required": [
"key1"
],
"additionalProperties": true
},
"anotherStringToMatch": {
"$id": "#/definitions/anotherStringToMatch",
"type": "object",
"properties": {
"key2": {
"type": "string"
}
},
"required": [
"key2"
],
"additionalProperties": true
}
},
"items": {
"$id": "#/items",
"type": "object",
"title": "main schema",
"description": "An explanation about the purpose of this instance.",
"default": {},
"examples": [],
"required": [
"name",
"matchMe",
"mergeMe"
],
"properties": {
"name": {
"$id": "#/items/name",
"type": "string",
"title": "The name schema",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": []
},
"matchMe": {
"$id": "#/items/matchMe",
"type": "string",
"title": "The matchMe schema",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": []
}
},
"allOf": [
{
"if": {
"properties": {
"matchMe": {
"pattern": "^stringToMatch:[0-9.]+"
}
}
},
"then": {
"allOf": [
{
"type": "object",
"properties": {
"mergeMe": {
"$ref": "#/definitions/stringToMatch"
}
}
}
]
}
},
{
"if": {
"properties": {
"gear": {
"pattern": "^anotherStringToMatch:[0-9.]+"
}
}
},
"then": {
"allOf": [
{
"type": "object",
"properties": {
"mergeMe": {
"$ref": "#/definitions/anotherStringToMatch"
}
}
}
]
}
}
],
"additionalProperties": true
}
}
What I want in JS would look something like
const schema = { name, matchMe }
if (matchMe == "string1") schema.mergeMe = ...subschema1;
else if (...)
else if (...)
but I just can't really work it out. Can someone help?
Edit: jsonschema.dev playground - the idea being if I specify the food as prefixed by "fruit" I have to give it "pips" and "berry", whereas if I specify "vegetable" I have to give it a totally differet schema, and they don't overlap.
https://jsonschema.dev/s/pHzGo
This actually ended up being a bug in the VSCode YAML extension that was ingesting my schema, causing the if blocks to not evaluate, and has been raised, fixed and released.
In plain English, I want a flexible schema that will allow an object called "message" to contain a couple of string props, and then a 3rd prop that can be either a plain string or another object. So, if it's defined thusly, is this achieving the goal or is there a validation gotcha that I am missing?
"message": {
"type": "object",
"properties": {
"another": {
"$ref": "another.schema.json"
},
"#type": {
"type": "string",
"enum": [
"One",
"Two",
"Three"
]
}
},
"allOf": [
{
"$ref": "#message"
},
{
"anyOf": [
{
"plainolstring": {
"type": "string"
}
},
{
"obj": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
}
}
}
}
]
}
]
}
}
And that would validate against either
"message": {
"another": "blah",
"#type": "foo",
"plainolstring": "sdfSR345w34"
}
or
"message": {
"another": "blah",
"#type": "foo",
"obj": {
"id":"sdfSR345w34",
"type": "guid"
}
}
Validating here against Schema v7 says that it is valid, but while it may be syntactically correct, would it achieve what I want?
Yes, anyOf will do what you want - except you have a syntax error by wrapping the subschemas with those properties "plainolstring" and "obj". The correct form would be:
{
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
}
}
}
]
}
Moreover, you don't even need the anyOf -- you can simplify that subschema to:
{
"type": ["string", "object"],
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
}
}
}
The properties keyword itself does not enforce that the type must be an object -- you need to use type for that. properties just says "if this is an object, this is the definition of those properties".
I have a sub-schema defined in nested objects and cannot make the enum constraint work. See here....
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"Top level": {
"type": "object",
"properties": {
"State": {
"type": "object",
"description": "stuff",
"properties": {
"Value": {
"type": "string",
"enum:": [
"A",
"B",
"C"
]
},
"readOnly": true
},
"required": [
"Value"
]
}
},
"required": [
"State"
]
}
},
"required": [
"Top level"
]
}
This should fail but instead it validates. Below...
{
"Top level": {
"State": {
"Value": "not supposed to validate but does anyway"
}
}
}
Oddly, this schema appears to work and block the undesired strings but it does not have the deeper sub-schema structure...
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"Value": {
"type": "string",
"enum": [
"A",
"B",
"C"
]
}
}
}
and this example properly gets rejected...
{
"Value": "D"
}
What am I doing wrong ? It must be something fundamental about nested objects.I know if I change the Value name, it detects it is missing and rejects during validation in the first example... why does it not detect the invalid enum strings ?
Any help would be appreciated !
This was really hard to spot for some reason. I thought I was going nuts too. You've got an extra : in there.
"enum:": [
^
My current json schema definition is like this
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"description": {
"type": "string",
"minLength": 1
},
"input": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": ["name", "description", "type"]
}
},
"output": {
"type": "array",
"maxItems": 1,
"items": {
"type": "object",
"properties": {
"description": {
"type": "string",
"minLength": 1
},
"type": {
"type": "string"
}
},
"required": ["description", "type"]
}
}
},
"required": ["name", "description"]
}
So I need to validate the scheme for the following conditions:
If input array and output array are empty, both must be required;
If the input array is not empty, then the output array should not be required;
If the output array is not empty, then the input array should not be required;
Thank you in advance.
Your first condition is the only one that we need to deal with. All properties are optional by default, so your conditions 2 and 3 translate to something like, "if the input array is not empty, then do nothing".
There are a couple of ways to achieve the first condition, but I suggest the following.
"allOf": {
"if": {
"properties": {
"input": { "const": [] },
"output": { "const": [] }
}
},
"then": { "required": ["input", "output"] }
}
it seems like all three of your requirements are self-fulfilling in json schema.
If input array and output array are empty, both must be required
if input and output are empty arrays, they are already present, so saying they are required is redundant. sort of, "if x is present with the value [], then x must be present". Jason's schema correctly expresses the way you've phrased this, but I don't think there's any way for that schema to cause a validation error.
and Jason's answer is correct on points 2 and 3.
I'd suggest you think about some example instances you would expect to fail validation (and add them to your question here), and that will help to construct a schema that adds the proper constraints.
I have the following use case with a JSON schema. I have a metadata object of a setting. In our case a setting can be of type string/real/integer/boolean.
In this object I have 4 fields: default/minimum/maximum each define a property of the setting.
Now what I want to achieve is that when the type of de default value is an integer, also the minimum/maximum values are integers.
The schema I have come up with so far:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"setting-value": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
}
]
},
"setting-meta": {
"type": "object",
"required": [
"name",
"type",
"default"
],
"properties": {
"name": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"Real",
"Integer",
"Boolean",
"String"
]
},
"minimum": {
"$ref": "#/definitions/setting-value"
},
"maximum": {
"$ref": "#/definitions/setting-value"
},
"default": {
"$ref": "#/definitions/setting-value"
},
"value": {
"$ref": "#/definitions/setting-value"
}
}
}
}
}
Here it is possible for the #/definitions/setting-meta to have support for the different types. However it does not define that if for example the value of TYPE is equal to Real/Integer that the types of minimum/maximum/default/value should all be of type number.
I would use these definitions as follows
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "schema-definition-above.json#/definitions/setting-meta"
}
According the the current schema, all examples below are VALID, however they should be valid/invalid as suggested:
Valid JSon object:
{
"name": "Enabled",
"type": "Boolean",
"minimum": false,
"maximum": true,
"default": true,
"value": true
}
Invalid json object, minimum/maximum/default don't have the same type:
{
"name": "Enabled",
"type": "Boolean",
"minimum": false,
"maximum": 1,
"default": "value",
"value": true
}
Invalid json object: type, does not match the actual type of the values
{
"name": "Enabled",
"unit": "enabled/disabled",
"configId": "Accumulator",
"displayName": "Enable or disable this machine",
"type": "Integer",
"minimum": false,
"maximum": true,
"default": true,
"value": true
}
My question:
Is it possible to put these kinds of dependencies into a JSON schema? The only kind of dependency I have foudn so far is with property dependencies indicating that if one property is set, another should also be set.
Any help would be much appreciated.
EDIT:
Extended that use case with some JSON objects that should be validated or invalidated with the referenced schema.
In order to do conditional validation where you have a known set of possible conditions, you should use the if/then/else keywords, in combination with with allOf.
In this schema, the first schema in allOf defines your general structure and overall requirements. The second schema applies the then constraint if the if schema validates successfully.
You would need to replicate the second schema for each condition that you have.
You can see this schema working at https://jsonschema.dev (link is preloaded with the below schema and sample data)
(The use of patternProperties is just a space saver. You could define each property individually.)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"allOf": [
{
"properties": {
"type": {
"enum": [
"Real",
"Integer",
"Boolean",
"String"
]
}
},
"required": [
"type",
"default",
"name"
]
},
{
"if": {
"properties": {
"type": {
"const": "String"
}
}
},
"then": {
"patternProperties": {
"^(minimum|maximum|default|value)$": {
"type": [
"string"
]
}
}
}
}
]
}