Как использовать Jsonschema Draft 7 if-then-else на основе логического значения? - PullRequest
0 голосов
/ 15 сентября 2018

Я пытаюсь определить схему json, которая требует некоторые поля, если поле управления имеет значение true.Я только что сделал следующую схему (я попробовал более одного решения от Google, поэтому есть некоторые различия между операторами if ...):

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "title": "The Root Schema",
  "if": {
    "not": {
      "properties": {
        "ldap_enable": {
          "enum": [ false ]
        }
      }
    }
  },
  "then": {
    "required": ["ldap_binddn", 
                 "ldap_bindpassword",
                 "ldap_server",
                 "ldap_searchdn",
                 "ldap_searchfilter",
                 "ldap_mappings",
                 "ldap_needtls" 
                ]
  },
  "if": {
    "properties" : {
      "telegram_alert": {
        "enum": [ 
        true 
       ]
      }
    }
   },
  "then": {
    "required": ["telegram_chat", 
                 "telegram_token"
                ]
  },
  "if": {
    "properties" : {
      "email_alert": {
        "enum": [ 
        true 
       ]
      }
    }
   },
  "then": {
    "required": ["email_sender", 
                 "email_host",
                 "email_port"
                ]
  },
  "required": [
    "mysql",
    "port",
    "tmp_path",
    "cookie_hash",
    "cookie_encryption",
    "web_host",
    "concurrency_mode",
    "max_parallel_tasks",
    "email_alert",
    "telegram_alert",
    "ldap_enable"
  ],
  "properties": {
    "mysql": {
      "$id": "#/properties/mysql",
      "type": "object",
      "title": "The Mysql Schema",
      "required": [
        "host",
        "user",
        "pass",
        "name"
      ],
      "properties": {
        "host": {
          "$id": "#/properties/mysql/properties/host",
          "type": "string",
          "title": "DB Address",
          "default": "db",
          "pattern": "^(.*)$"
        },
        "user": {
          "$id": "#/properties/mysql/properties/user",
          "type": "string",
          "title": "Username for DB",
          "default": "semaphore",
          "pattern": "^(.*)$"
        },
        "pass": {
          "$id": "#/properties/mysql/properties/pass",
          "type": "string",
          "title": "User Password",
          "default": "semaphore",
          "pattern": "^(.*)$"
        },
        "name": {
          "$id": "#/properties/mysql/properties/name",
          "type": "string",
          "title": "Schema Name on DB",
          "default": "semaphore",
          "pattern": "^(.*)$"
        }
      }
    },
    "port": {
      "$id": "#/properties/port",
      "type": "string",
      "title": "The port where app will listen.",
      "default": "3000"
    },
    "tmp_path": {
      "$id": "#/properties/tmp_path",
      "type": "string",
      "title": "The path where the playbooks will be temporary placed.",
      "default": "/tmp",
      "pattern": "^(.*)$"
    },
    "cookie_hash": {
      "$id": "#/properties/cookie_hash",
      "type": "string",
      "title": "Cookie Hash for Site",
      "pattern": "^(.*)$"
    },
    "cookie_encryption": {
      "$id": "#/properties/cookie_encryption",
      "type": "string",
      "title": "The Cookie_encryption",
      "pattern": "^(.*)$"
    },
    "email_sender": {
      "$id": "#/properties/email_sender",
      "type": "string",
      "default": "semaphore@localhost",
      "pattern": "^(.*)$"
    },
    "email_host": {
      "$id": "#/properties/email_host",
      "type": "string",
      "title": "The Email_host Schema",
      "pattern": "^(.*)$"
    },
    "email_port": {
      "$id": "#/properties/email_port",
      "type": "string",
      "title": "The Email_port Schema",
      "pattern": "^(.*)$"
    },
    "web_host": {
      "$id": "#/properties/web_host",
      "type": "string",
      "title": "The Web_host Schema",
      "default": "http://localhost:3000",
      "pattern": "^(.*)$"
    },
    "ldap_binddn": {
      "$id": "#/properties/ldap_binddn",
      "type": "string",
      "title": "Ldap Bind User.",
      "examples": [
        "cn=bla,dc=com"
      ],
      "pattern": "^(.*)$"
    },
    "ldap_bindpassword": {
      "$id": "#/properties/ldap_bindpassword",
      "type": "string",
      "title": "Ldap Bind Password",
      "pattern": "^(.*)$"
    },
    "ldap_server": {
      "$id": "#/properties/ldap_server",
      "type": "string",
      "title": "Ldap Server",
      "default": "ldap",
      "pattern": "^(.*)$"
    },
    "ldap_searchdn": {
      "$id": "#/properties/ldap_searchdn",
      "type": "string",
      "title": "The Ldap_searchdn Schema",
      "examples": [
        "ou=user,dc=example"
      ],
      "pattern": "^(.*)$"
    },
    "ldap_searchfilter": {
      "$id": "#/properties/ldap_searchfilter",
      "type": "string",
      "title": "The Ldap_searchfilter Schema",
      "examples": [
        "(uid=%s)"
      ],
      "pattern": "^(.*)$"
    },
    "ldap_mappings": {
      "$id": "#/properties/ldap_mappings",
      "type": "object",
      "title": "The Ldap_mappings Schema",
      "required": [
        "dn",
        "mail",
        "uid",
        "cn"
      ],
      "properties": {
        "dn": {
          "$id": "#/properties/ldap_mappings/properties/dn",
          "type": "string",
          "title": "The Dn Schema",
          "default": "dn",
          "examples": [
            "dn"
          ],
          "pattern": "^(.*)$"
        },
        "mail": {
          "$id": "#/properties/ldap_mappings/properties/mail",
          "type": "string",
          "title": "The Mail Schema",
          "default": "mail",
          "examples": [
            "mail"
          ],
          "pattern": "^(.*)$"
        },
        "uid": {
          "$id": "#/properties/ldap_mappings/properties/uid",
          "type": "string",
          "title": "The Uid Schema",
          "default": "uid",
          "examples": [
            "uid"
          ],
          "pattern": "^(.*)$"
        },
        "cn": {
          "$id": "#/properties/ldap_mappings/properties/cn",
          "type": "string",
          "title": "The Cn Schema",
          "default": "cn",
          "examples": [
            "cn"
          ],
          "pattern": "^(.*)$"
        }
      }
    },
    "telegram_chat": {
      "$id": "#/properties/telegram_chat",
      "type": "string",
      "title": "The Telegram_chat Schema",
      "examples": [
        "asdfasdf"
      ],
      "pattern": "^(.*)$"
    },
    "telegram_token": {
      "$id": "#/properties/telegram_token",
      "type": "string",
      "title": "The Telegram_token Schema",
      "examples": [
        "asdfasdf"
      ],
      "pattern": "^(.*)$"
    },
    "concurrency_mode": {
      "$id": "#/properties/concurrency_mode",
      "type": "string",
      "title": "The Concurrency_mode Schema",
      "default": "",
      "examples": [
        ""
      ],
      "pattern": "^(.*)$"
    },
    "max_parallel_tasks": {
      "$id": "#/properties/max_parallel_tasks",
      "type": "integer",
      "title": "The Max_parallel_tasks Schema",
      "default": 0
    },
    "email_alert": {
      "$id": "#/properties/email_alert",
      "type": "boolean",
      "title": "The Email_alert Schema",
      "default": false,
      "examples": [
        true
      ]
    },
    "telegram_alert": {
      "$id": "#/properties/telegram_alert",
      "type": "boolean",
      "title": "The Telegram_alert Schema",
      "default": false,
      "examples": [
        true
      ]
    },
    "ldap_enable": {
      "$id": "#/properties/ldap_enable",
      "type": "boolean",
      "title": "The Ldap_enable Schema",
      "default": false,
      "examples": [
        true
      ]
    },
    "ldap_needtls": {
      "$id": "#/properties/ldap_needtls",
      "type": "boolean",
      "title": "The Ldap_needtls Schema",
      "default": false,
      "examples": [
        true
      ]
    }
  }
}

Затем я просто проверил следующий json по схеме:

{
    "mysql": {
        "host": "db",
        "user": "semaphore",
        "pass": "semaphore",
        "name": "semaphore"
    },
    "port": "",
    "tmp_path": "/bla",
    "cookie_hash": "93n2lvoStnqjskpqea5P+04hPo1CEoEj9fJ68BARtYA=",
    "cookie_encryption": "602ZDI0qYlScN+FH6ivx75ERWfS+0E4aHV5WaYGHI4s=",
    "email_sender": "semaphore@localhost",
    "email_host": "server",
    "email_port": "25",
    "web_host": "http://whoknows",
    "telegram_chat": "asdfasdf",
    "telegram_token": "asdfasdf",
    "concurrency_mode": "",
    "max_parallel_tasks": 0,
    "email_alert": true,
    "telegram_alert": true,
    "ldap_enable": true,
    "ldap_needtls": true
 }

Я только что ожидал здесь ошибки проверки, поля ldap_ * должны быть обязательными, поскольку ldap_enable имеет значение true, но вместо этого "https://www.jsonschemavalidator.net/" site и python jsonschema lib возвращает, что json действителен.

1 Ответ

0 голосов
/ 17 сентября 2018

У вас есть дублирование ключевых слов (if, then) на корневом уровне вашей схемы. Если требуется несколько условий, вы можете сгруппировать их с массивами oneOf, allOf, anyOf в зависимости от ваших требований.

Пожалуйста, проверьте эту схему:

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "title": "The Root Schema",
  "allOf": [
    {
      "if": {
        "properties": {
          "ldap_enable": {
            "enum": [
              true
            ]
          }
        }
      },
      "then": {
        "required": [
          "ldap_binddn",
          "ldap_bindpassword",
          "ldap_server",
          "ldap_searchdn",
          "ldap_searchfilter",
          "ldap_mappings",
          "ldap_needtls"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "telegram_alert": {
            "enum": [
              true
            ]
          }
        }
      },
      "then": {
        "required": [
          "telegram_chat",
          "telegram_token"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "email_alert": {
            "enum": [
              true
            ]
          }
        }
      },
      "then": {
        "required": [
          "email_sender",
          "email_host",
          "email_port"
        ]
      }
    }
  ],
  "required": [
    "mysql",
    "port",
    "tmp_path",
    "cookie_hash",
    "cookie_encryption",
    "web_host",
    "concurrency_mode",
    "max_parallel_tasks",
    "email_alert",
    "telegram_alert",
    "ldap_enable"
  ],
  "properties": {
    "mysql": {
      "$id": "#/properties/mysql",
      "type": "object",
      "title": "The Mysql Schema",
      "required": [
        "host",
        "user",
        "pass",
        "name"
      ],
      "properties": {
        "host": {
          "$id": "#/properties/mysql/properties/host",
          "type": "string",
          "title": "DB Address",
          "default": "db",
          "pattern": "^(.*)$"
        },
        "user": {
          "$id": "#/properties/mysql/properties/user",
          "type": "string",
          "title": "Username for DB",
          "default": "semaphore",
          "pattern": "^(.*)$"
        },
        "pass": {
          "$id": "#/properties/mysql/properties/pass",
          "type": "string",
          "title": "User Password",
          "default": "semaphore",
          "pattern": "^(.*)$"
        },
        "name": {
          "$id": "#/properties/mysql/properties/name",
          "type": "string",
          "title": "Schema Name on DB",
          "default": "semaphore",
          "pattern": "^(.*)$"
        }
      }
    },
    "port": {
      "$id": "#/properties/port",
      "type": "string",
      "title": "The port where app will listen.",
      "default": "3000"
    },
    "tmp_path": {
      "$id": "#/properties/tmp_path",
      "type": "string",
      "title": "The path where the playbooks will be temporary placed.",
      "default": "/tmp",
      "pattern": "^(.*)$"
    },
    "cookie_hash": {
      "$id": "#/properties/cookie_hash",
      "type": "string",
      "title": "Cookie Hash for Site",
      "pattern": "^(.*)$"
    },
    "cookie_encryption": {
      "$id": "#/properties/cookie_encryption",
      "type": "string",
      "title": "The Cookie_encryption",
      "pattern": "^(.*)$"
    },
    "email_sender": {
      "$id": "#/properties/email_sender",
      "type": "string",
      "default": "semaphore@localhost",
      "pattern": "^(.*)$"
    },
    "email_host": {
      "$id": "#/properties/email_host",
      "type": "string",
      "title": "The Email_host Schema",
      "pattern": "^(.*)$"
    },
    "email_port": {
      "$id": "#/properties/email_port",
      "type": "string",
      "title": "The Email_port Schema",
      "pattern": "^(.*)$"
    },
    "web_host": {
      "$id": "#/properties/web_host",
      "type": "string",
      "title": "The Web_host Schema",
      "default": "http://localhost:3000",
      "pattern": "^(.*)$"
    },
    "ldap_binddn": {
      "$id": "#/properties/ldap_binddn",
      "type": "string",
      "title": "Ldap Bind User.",
      "examples": [
        "cn=bla,dc=com"
      ],
      "pattern": "^(.*)$"
    },
    "ldap_bindpassword": {
      "$id": "#/properties/ldap_bindpassword",
      "type": "string",
      "title": "Ldap Bind Password",
      "pattern": "^(.*)$"
    },
    "ldap_server": {
      "$id": "#/properties/ldap_server",
      "type": "string",
      "title": "Ldap Server",
      "default": "ldap",
      "pattern": "^(.*)$"
    },
    "ldap_searchdn": {
      "$id": "#/properties/ldap_searchdn",
      "type": "string",
      "title": "The Ldap_searchdn Schema",
      "examples": [
        "ou=user,dc=example"
      ],
      "pattern": "^(.*)$"
    },
    "ldap_searchfilter": {
      "$id": "#/properties/ldap_searchfilter",
      "type": "string",
      "title": "The Ldap_searchfilter Schema",
      "examples": [
        "(uid=%s)"
      ],
      "pattern": "^(.*)$"
    },
    "ldap_mappings": {
      "$id": "#/properties/ldap_mappings",
      "type": "object",
      "title": "The Ldap_mappings Schema",
      "required": [
        "dn",
        "mail",
        "uid",
        "cn"
      ],
      "properties": {
        "dn": {
          "$id": "#/properties/ldap_mappings/properties/dn",
          "type": "string",
          "title": "The Dn Schema",
          "default": "dn",
          "examples": [
            "dn"
          ],
          "pattern": "^(.*)$"
        },
        "mail": {
          "$id": "#/properties/ldap_mappings/properties/mail",
          "type": "string",
          "title": "The Mail Schema",
          "default": "mail",
          "examples": [
            "mail"
          ],
          "pattern": "^(.*)$"
        },
        "uid": {
          "$id": "#/properties/ldap_mappings/properties/uid",
          "type": "string",
          "title": "The Uid Schema",
          "default": "uid",
          "examples": [
            "uid"
          ],
          "pattern": "^(.*)$"
        },
        "cn": {
          "$id": "#/properties/ldap_mappings/properties/cn",
          "type": "string",
          "title": "The Cn Schema",
          "default": "cn",
          "examples": [
            "cn"
          ],
          "pattern": "^(.*)$"
        }
      }
    },
    "telegram_chat": {
      "$id": "#/properties/telegram_chat",
      "type": "string",
      "title": "The Telegram_chat Schema",
      "examples": [
        "asdfasdf"
      ],
      "pattern": "^(.*)$"
    },
    "telegram_token": {
      "$id": "#/properties/telegram_token",
      "type": "string",
      "title": "The Telegram_token Schema",
      "examples": [
        "asdfasdf"
      ],
      "pattern": "^(.*)$"
    },
    "concurrency_mode": {
      "$id": "#/properties/concurrency_mode",
      "type": "string",
      "title": "The Concurrency_mode Schema",
      "default": "",
      "examples": [
        ""
      ],
      "pattern": "^(.*)$"
    },
    "max_parallel_tasks": {
      "$id": "#/properties/max_parallel_tasks",
      "type": "integer",
      "title": "The Max_parallel_tasks Schema",
      "default": 0
    },
    "email_alert": {
      "$id": "#/properties/email_alert",
      "type": "boolean",
      "title": "The Email_alert Schema",
      "default": false,
      "examples": [
        true
      ]
    },
    "telegram_alert": {
      "$id": "#/properties/telegram_alert",
      "type": "boolean",
      "title": "The Telegram_alert Schema",
      "default": false,
      "examples": [
        true
      ]
    },
    "ldap_enable": {
      "$id": "#/properties/ldap_enable",
      "type": "boolean",
      "title": "The Ldap_enable Schema",
      "default": false,
      "examples": [
        true
      ]
    },
    "ldap_needtls": {
      "$id": "#/properties/ldap_needtls",
      "type": "boolean",
      "title": "The Ldap_needtls Schema",
      "default": false,
      "examples": [
        true
      ]
    }
  }
}
...