Ansible picked up support for jsonschema, and I have a variety of use cases for it, but most all of them require conditionals. I have been reading the doc's for jsonschema and draft-7 if-then-else, and tried several permutations, and seemingly only get half of my target handled. Hoping someone can help pave the way with a practical example for me that I can deconstruct.
Two possibilities based on the bool in "send_notifications":
{
"capture_state": "value here",
"send_notifications": true,
"user_email_list": ["email@something.com", "email2@something.com"],
"host_info": [
{
"ansible_host": "192.20.xxx.xxx",
"ECRTicket": "1103035"
},
.... continued
]
}
or
{
"capture_state": "value here",
"send_notifications": false
}
Essentially, only allow, and require the properties shown in the examples based on the bool in "send_notifications", and unconditionally fail if its neither of these two schemas. I'll likely improve this more with patterns as well, but just these keys and types are a great start.
I had initially generated the following base schema to use as a reference to manipulate and add the conditionals, and perhaps it is something in this schema that conflicts with using conditionals and additionalProperties:false, but being new to jsonschema it's not immediately obvious to me, so reaching out for some assistance so I can put this to use more often. Any help would be appreciated, thank you for your time, new to posting on stack, if I can improve my question please let me know.
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": [
"capture_state",
"send_notifications",
"user_email_list",
"host_info"
],
"properties": {
"capture_state": {
"type": "string"
},
"send_notifications": {
"type": "boolean"
},
"user_email_list": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
}
]
}
},
"host_info": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"required": [
"ansible_host",
"ECRTicket"
],
"properties": {
"ansible_host": {
"type": "string"
},
"ECRTicket": {
"type": "string"
}
},
"additionalProperties": false
}
]
}
}
},
"additionalProperties": false
}
Generally, you're going to have a hard time whenever you choose to restrict unknown properties. I'll assume you have a good reason and including it is worth it.
There are a couple ways to do this. I'm presenting it this way because it produces the best messages when a JSON instance fails schema validation.
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"capture_state": { "type": "string" },
"send_notifications": { "type": "boolean" },
},
"required": ["capture_state", "send_notifications"],
"if": {
"properties": {
"send_notifications": { "const": true },
},
"required": ["send_notifications"]
},
"then": {
"properties": {
"capture_state": true,
"send_notifications": true,
"user_email_list": {
"type": "array",
"items": { "type": "string" }
},
"host_info": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ansible_host": { "type": "string" },
"ECRTicket": { "type": "string" }
},
"required": ["ansible_host", "ECRTicket"],
"additionalProperties": false
}
}
},
"required": ["user_email_list", "host_info"],
"additionalProperties": false
},
"else": {
"properties": {
"capture_state": true,
"send_notifications": true
},
"additionalProperties": false
}
}
additionalProperties
only recognizes properties declared in the same sub-schema it appears in. That means you need to include some dummy properties
entries so it knows about the properties that are declared elsewhere in the schema.
I assume ansible doesn't support more recent versions of JSON Schema than draft-07? If it does, you can use unevaluatedProperties
instead of additionalProperties
to avoid jumping through some of the hoops you have to with additionalProperties
.
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"capture_state": { "type": "string" },
"send_notifications": { "type": "boolean" },
},
"required": ["capture_state", "send_notifications"],
"unevaluatedProperties": false,
"if": {
"properties": {
"send_notifications": { "const": true },
},
"required": ["send_notifications"]
},
"then": {
"properties": {
"user_email_list": {
"type": "array",
"items": { "type": "string" }
},
"host_info": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ansible_host": { "type": "string" },
"ECRTicket": { "type": "string" }
},
"required": ["ansible_host", "ECRTicket"],
"additionalProperties": false
}
}
},
"required": ["user_email_list", "host_info"]
}
}
If anyone at Ansible happens to see this, draft 2020-12 includes unevaluatedProperties
and will get a lot of implementation support as it is also included in OpenAPI 3.1.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.