我正在尝试编写架构以验证AWS IAM安全组必须指定传入IP地址“0.0.0.0/0”可以连接到端口22。
我正在使用oneOf运算符并定义两组属性,我的直觉是如果两个属性都满足,则JSON模式应该失败但不会失败。
示例JSON -
{
"ipPermissions": [
{
"toPort": -1,
"fromPort": -1,
"ipRanges": [
"10.0.0.0/16"
]
},
{
"toPort": 22,
"fromPort": 53,
"ipRanges": [
"0.0.0.0/0"
],
"ipProtocol": "tcp"
}
]
}
上述JSON 应该失败,因为ipPermission[1]
对象是
{
"toPort": 22,
"fromPort": 53,
"ipRanges": [
"0.0.0.0/0"
],
"ipProtocol": "tcp"
}
当ipRanges
为0.0.0.0/0
时,toPort
的值为22
以下JSON文档应通过验证 -
{
"ipPermissions": [
{
"toPort": 22,
"fromPort": -1,
"ipRanges": [
"10.0.0.0/16"
]
},
{
"toPort": 22,
"fromPort": 53,
"ipRanges": [
"somethingElse"
],
"ipProtocol": "tcp"
}
]
}
因为ipPermissions
index [0]对象的toPort
值22
,但ipRanges[0]
的值10.0.0.0/16
不是0.0.0.0/0
以下JSON不应通过验证 -
{
"ipPermissions": [
{
"toPort": 22,
"fromPort": -1,
"ipRanges": [
"10.0.0.0/16"
]
},
{
"toPort": 22,
"fromPort": 53,
"ipRanges": [
"somethingElse",
"0.0.0.0/0"
],
"ipProtocol": "tcp"
}
]
}
ipPermissions[1].ipRanges[1]
值为0.0.0.0/0
我的JSON架构 -
{
"$schema": "http://json-schema.org/draft-04/schema#",
"required": [
"ipPermissions"
],
"properties": {
"ipPermissions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"oneOf": {
"ipRanges": {
"type": "array",
"items": {
"type": "string",
"value": "0.0.0.0/0"
}
},
"toPort": {
"type": "integer",
"minimum": 23
}
}
}
}
}
}
}
答案 0 :(得分:3)
这个有点复杂,所以我使用oneOf
将其分解,以便更容易理解。
一般策略是首先定义属性,然后使用allOf
,not
,dependencies
,not
和/或{{1分别添加复杂约束}}。在这种情况下,我采用的方法是定义一个匹配您要禁止的情况的模式,如果该模式匹配则使用contains
验证失败。
这是验证“toPort”是否为“22”且“ipRanges”数组是否包含“0.0.0.0/0”的模式。不幸的是,JSON Schema还没有contains
关键字,所以我们必须做一些布尔逻辑体操来表达这种约束。
我们不能直接约束数组包含“0.0.0.0/0”,但是我们可以创建一个禁止“0.0.0.0/0”在数组中的模式。如果这样的模式在数组中不存在“0.0.0.0 \ 0”时有效,那么任何未验证的JSON必须至少包含一个“0.0.0.0/0”的实例。
这描述了禁止用于实现{
"type": "object",
"required": ["ipPermissions"],
"properties": {
"ipPermissions": {
"type": "array",
"items": { "$ref": "#/definitions/ipPermission" }
}
},
"definitions": {
"ipPermission": {
"type": "object",
"properties": {
"toPort": { ... },
"fromPort": { ... },
"ipRanges": { ... },
"ipProtocol": { ... }
}
"not": { "$ref": "#/definitions/port-22-and-0.0.0.0-0"}
},
"port-22-and-0.0.0.0-0": {
"type": "object",
"properties": {
"toPort": { "enum": [22] },
"ipRanges": { "$ref": "#/definitions/array-contains-0.0.0.0-0" }
},
"required": ["toPort", "ipRanges"]
},
"array-contains-0.0.0.0-0": {
"not": { "$ref": "#/definitions/array-without-0.0.0.0-0" }
},
"array-without-0.0.0.0-0": {
"type": "array",
"items": {
"not": { "enum": ["0.0.0.0/0"] }
}
}
}
}
约束的“0.0.0.0/0”的数组。
{{1}}
答案 1 :(得分:0)
您需要添加" required"节点到您的架构。但是,在这种情况下,还需要指定N个允许节点中的一个:
{
"$schema":"http://json-schema.org/draft-04/schema#",
"required":[
"ipPermissions"
],
"properties":{
"ipPermissions":{
"type":"array",
"items":{
"type":"object",
"properties":{
"oneOf":{
"ipRanges":{
"type":"array",
"items":{
"type":"string",
"value":"0.0.0.0/0"
}
},
"toPort":{
"type":"integer",
"minimum":23
}
}
},
"oneOf":[
{
"required":[
"ipRanges"
]
},
{
"required":[
"toPort"
]
}
]
}
}
}
}
这将使用 ipRanges 节点或 toPort 节点验证实例,但不能同时验证两者,例如:
{
"ipPermissions":[
{
"toPort":-1,
"fromPort":-1
},
{
"fromPort":53,
"ipRanges":[
"0.0.0.0/0"
],
"ipProtocol":"tcp"
}
]
}