Also use OpenAPI-enforcer to check the OpenAPI specs in addition

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER 2021-02-01 13:56:27 +01:00
parent 020a8f81dd
commit 1ae67e8fbb
No known key found for this signature in database
GPG Key ID: 00135ACBD90B28DD
15 changed files with 213 additions and 123 deletions

92
package-lock.json generated
View File

@ -151,18 +151,6 @@
"yargs": "15.3.1"
},
"dependencies": {
"ajv": {
"version": "6.12.5",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
"integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"chalk": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
@ -248,6 +236,18 @@
"es6-promisify": "^5.0.0"
}
},
"ajv": {
"version": "6.12.5",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
"integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ajv-oai": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/ajv-oai/-/ajv-oai-1.2.0.tgz",
@ -410,6 +410,15 @@
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
"dev": true
},
"axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"dev": true,
"requires": {
"follow-redirects": "^1.10.0"
}
},
"backslash": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/backslash/-/backslash-0.2.0.tgz",
@ -874,14 +883,6 @@
"ast-types": "0.x.x",
"escodegen": "1.x.x",
"esprima": "3.x.x"
},
"dependencies": {
"esprima": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
"dev": true
}
}
},
"depd": {
@ -980,12 +981,20 @@
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
},
"dependencies": {
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
}
}
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
"dev": true
},
"estraverse": {
@ -1255,6 +1264,12 @@
}
}
},
"follow-redirects": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz",
"integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==",
"dev": true
},
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@ -1982,6 +1997,14 @@
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
},
"dependencies": {
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
}
}
},
"jsep": {
@ -2353,6 +2376,29 @@
"format-util": "^1.0.3"
}
},
"openapi-enforcer": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/openapi-enforcer/-/openapi-enforcer-1.13.1.tgz",
"integrity": "sha512-NDDmyonl3bgxP+RabJsTPxn8EEza4Aet5zEocfX6nP9LL0J52aNFMYxNHoAuqoY3zQcZG2pnm3DMi2gYiRYbQg==",
"dev": true,
"requires": {
"axios": "^0.21.1",
"json-schema-ref-parser": "^6.1.0"
},
"dependencies": {
"json-schema-ref-parser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-6.1.0.tgz",
"integrity": "sha512-pXe9H1m6IgIpXmE5JSb8epilNTGsmTb2iPohAXpOdhqGFbQjNeHHsZxU+C8w6T81GZxSPFLeUoqDJmzxx5IGuw==",
"dev": true,
"requires": {
"call-me-maybe": "^1.0.1",
"js-yaml": "^3.12.1",
"ono": "^4.0.11"
}
}
}
},
"optionator": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",

View File

@ -17,10 +17,12 @@
"scripts": {
"set-threshold": "echo '{\"warnings\": 0}' > .thresholdrc",
"delete-threshold": "rm .thresholdrc",
"openapi-validator": "lint-openapi -p -c test/ibm-openapi-validator.rc src/api/docs/content/specs/main.yaml 2> /dev/null",
"test": "npm run set-threshold && npm run openapi-validator && npm run delete-threshold"
"openapi-validator": "lint-openapi -p -c test/api/ibm-openapi-validator.rc src/api/docs/content/specs/main.yaml 2> /dev/null",
"openapi-enforcer": "node test/api/openapi-enforcer.js",
"test": "npm run set-threshold && npm run openapi-validator && npm run openapi-enforcer && npm run delete-threshold"
},
"devDependencies": {
"ibm-openapi-validator": "^0.34.1"
"ibm-openapi-validator": "^0.34.1",
"openapi-enforcer": "^1.13.1"
}
}

View File

@ -21,9 +21,12 @@ components:
schema:
$ref: '#/components/schemas/session'
examples:
- $ref: '#/components/examples/login_okay'
- $ref: '#/components/examples/no_login_required'
- $ref: '#/components/examples/login_required'
login_okay:
$ref: '#/components/examples/login_okay'
no_login_required:
$ref: '#/components/examples/no_login_required'
login_required:
$ref: '#/components/examples/login_required'
'401':
description: Unauthorized
@ -52,8 +55,10 @@ components:
schema:
$ref: '#/components/schemas/session'
examples:
- $ref: '#/components/examples/login_okay'
- $ref: '#/components/examples/no_login_required'
login_okay:
$ref: '#/components/examples/login_okay'
no_login_required:
$ref: '#/components/examples/no_login_required'
'400':
description: Bad Request
content:
@ -61,9 +66,12 @@ components:
schema:
$ref: '#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/no_payload'
- $ref: '#/components/examples/errors/no_response'
- $ref: '#/components/examples/errors/response_inval'
no_payload:
$ref: '#/components/examples/errors/no_payload'
no_response:
$ref: '#/components/examples/errors/no_response'
response_inval:
$ref: '#/components/examples/errors/response_inval'
'401':
description: Unauthorized
content:
@ -87,7 +95,8 @@ components:
schema:
$ref: '#/components/schemas/session'
examples:
- $ref: '#/components/examples/no_login_required'
no_login_required:
$ref: '#/components/examples/no_login_required'
'401':
description: Unauthorized
content:
@ -101,7 +110,8 @@ components:
schema:
$ref: '#/components/schemas/session'
examples:
- $ref: '#/components/examples/login_failed'
login_failed:
$ref: '#/components/examples/login_failed'
schemas:
session:
@ -193,18 +203,18 @@ components:
error:
key: "bad_request"
message: "No valid JSON payload found"
data: null
hint: null
no_response:
summary: Bad request (no response)
value:
error:
key: "bad_request"
message: "No response found in JSON payload"
data: null
hint: null
response_inval:
summary: Bad request (invalid response)
value:
error:
key: "bad_request"
message: "Invalid response length"
data: null
hint: null

View File

@ -24,7 +24,8 @@ components:
schema:
$ref: '#/components/schemas/clients/get'
examples:
- $ref: '#/components/examples/clients'
clients:
$ref: '#/components/examples/clients'
'401':
description: Unauthorized
content:
@ -61,8 +62,10 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/uri_error/item_missing'
- $ref: '#/components/examples/errors/bad_request/no_payload'
item_missing:
$ref: '#/components/examples/errors/uri_error/item_missing'
no_payload:
$ref: '#/components/examples/errors/bad_request/no_payload'
'401':
description: Unauthorized
content:
@ -86,7 +89,8 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/uri_error/item_missing'
item_missing:
$ref: '#/components/examples/errors/uri_error/item_missing'
'401':
description: Unauthorized
content:
@ -124,6 +128,9 @@ components:
application/json:
schema:
$ref: '#/components/schemas/clients/get' # identical to GET
headers:
Location:
$ref: 'common.yaml#/components/headers/Location'
'400':
description: Bad request
content:
@ -131,8 +138,10 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/bad_request/no_payload'
- $ref: '#/components/examples/errors/database_error/duplicate'
no_payload:
$ref: '#/components/examples/errors/bad_request/no_payload'
duplicate:
$ref: '#/components/examples/errors/database_error/duplicate'
'401':
description: Unauthorized
content:
@ -167,7 +176,6 @@ components:
client:
description: client IP / MAC / hostname / interface
type: string
required: true
example: 127.0.0.1
comment:
type: object
@ -175,7 +183,6 @@ components:
comment:
description: User-provided free-text comment for this client (may be `null` if not specified)
type: string
required: false
nullable: true
default: null
example: Some comment for this client
@ -194,12 +201,10 @@ components:
description: Array of group IDs
type: array
default: [0]
required: false
items:
type: integer
readonly:
type: object
summary: Readonly properties of a single client
properties:
id:
description: Database ID
@ -218,7 +223,6 @@ components:
example: 1611239099
examples:
clients:
name: Example clients
value:
clients:
- client: "127.0.0.1"

View File

@ -34,6 +34,12 @@ components:
description: "Human-readable error message"
example: "Unauthorized"
hint:
type: 'null'
type: string
nullable: true
description: "No additional data available"
example: null
example: null
headers:
Location:
description: Location of created resource
schema:
type: string

View File

@ -94,9 +94,8 @@ components:
type: object
properties:
blocking:
type: bool
type: boolean
description: Blocking status
required: true
example: true
timer:
type: object
@ -104,9 +103,7 @@ components:
timer:
type: integer
description: Remaining seconds until blocking mode is automatically changed
required: false
nullable: true
default: null
example: 15
cache_size:
type: object
@ -145,8 +142,9 @@ components:
type: string
description: "Human-readable error message"
example: "No \\\"blocking\\\" boolean in body data"
data:
type: null
hint:
type: string
nullable: true
description: "Additional data (if available)"
example: null
no_payload:
@ -164,7 +162,8 @@ components:
type: string
description: "Human-readable error message"
example: "Invalid request body data (no valid JSON)"
data:
type: null
hint:
type: string
nullable: true
description: "Additional data (if available)"
example: null

View File

@ -42,7 +42,8 @@ components:
schema:
$ref: '#/components/schemas/domains/get'
examples:
- $ref: '#/components/examples/domains'
domains:
$ref: '#/components/examples/domains'
'401':
description: Unauthorized
content:
@ -79,7 +80,8 @@ components:
schema:
$ref: '#/components/schemas/domains/get'
examples:
- $ref: '#/components/examples/domains'
domains:
$ref: '#/components/examples/domains'
'400':
description: Bad request
content:
@ -87,11 +89,16 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/uri_error/list_imprecise'
- $ref: '#/components/examples/errors/uri_error/item_missing'
- $ref: '#/components/examples/errors/bad_request/no_payload'
- $ref: '#/components/examples/errors/database_error/duplicate'
- $ref: '#/components/examples/errors/regex_error/invalid_regex'
list_imprecise:
$ref: '#/components/examples/errors/uri_error/list_imprecise'
item_missing:
$ref: '#/components/examples/errors/uri_error/item_missing'
no_payload:
$ref: '#/components/examples/errors/bad_request/no_payload'
duplicate:
$ref: '#/components/examples/errors/database_error/duplicate'
invalid_regex:
$ref: '#/components/examples/errors/regex_error/invalid_regex'
'401':
description: Unauthorized
content:
@ -115,8 +122,10 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/uri_error/list_imprecise'
- $ref: '#/components/examples/errors/uri_error/item_missing'
list_imprecise:
$ref: '#/components/examples/errors/uri_error/list_imprecise'
item_missing:
$ref: '#/components/examples/errors/uri_error/item_missing'
'401':
description: Unauthorized
content:
@ -155,6 +164,9 @@ components:
application/json:
schema:
$ref: '#/components/schemas/domains/get'
headers:
Location:
$ref: 'common.yaml#/components/headers/Location'
'400':
description: Bad request
content:
@ -162,10 +174,14 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/uri_error/list_imprecise'
- $ref: '#/components/examples/errors/bad_request/no_payload'
- $ref: '#/components/examples/errors/database_error/duplicate'
- $ref: '#/components/examples/errors/regex_error/invalid_regex'
list_imprecise:
$ref: '#/components/examples/errors/uri_error/list_imprecise'
no_payload:
$ref: '#/components/examples/errors/bad_request/no_payload'
duplicate:
$ref: '#/components/examples/errors/database_error/duplicate'
invalid_regex:
$ref: '#/components/examples/errors/regex_error/invalid_regex'
'401':
description: Unauthorized
content:
@ -207,37 +223,33 @@ components:
domain:
description: Domain
type: string
required: true
example: testdomain.com
type:
type: object
properties:
type:
description: String specifying domain type
type: enum
required: true
type: string
enum:
- allow
- deny
example: allow
- "allow"
- "deny"
example: "allow"
kind:
type: object
properties:
kind:
description: String specifying domain kind
type: enum
required: true
type: string
enum:
- exact
- regex
example: exact
- "exact"
- "regex"
example: "exact"
comment:
type: object
properties:
comment:
description: User-provided free-text comment for this domain (may be `null` if not specified)
type: string
required: false
nullable: true
default: null
example: Some comment describing this domain
@ -247,7 +259,6 @@ components:
groups:
description: Array of group IDs
type: array
required: false
items:
type: integer
enabled:
@ -256,11 +267,9 @@ components:
enabled:
description: Status of domain
type: boolean
required: false
default: true
readonly:
type: object
summary: Readonly properties of a domain
properties:
id:
description: Database ID
@ -276,7 +285,7 @@ components:
readOnly: true
examples:
domains:
name: Example domains
summary: Example domains
value:
domains:
- domain: "allowed.com"

View File

@ -156,11 +156,9 @@ components:
properties:
timestamp:
type: integer
readonly: true
description: Unix timestamp of log line creation (server time)
message:
type: string
readonly: true
description: Log line content
example:
- timestamp: 1611729969
@ -248,13 +246,13 @@ components:
type: array
description: raw values
items:
type: float
type: number
example: [0.58837890625, 0.64990234375, 0.66748046875]
percent:
type: array
description: raw values
items:
type: float
type: number
example: [4.903157711029053, 5.415853023529053, 5.562337398529053]
sensors:
type: array
@ -264,16 +262,13 @@ components:
properties:
name:
type: string
readonly: true
nullable: true
description: Description of temperature sensor (if available, `null` otherwise)
path:
type: string
readonly: true
description: Short path of temperature sensor
value:
type: float
readonly: true
type: number
description: Sensor value
example:
- name: null

View File

@ -24,7 +24,8 @@ components:
schema:
$ref: '#/components/schemas/groups/get'
examples:
- $ref: '#/components/examples/groups'
groups:
$ref: '#/components/examples/groups'
'401':
description: Unauthorized
content:
@ -61,8 +62,10 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/uri_error/item_missing'
- $ref: '#/components/examples/errors/bad_request/no_payload'
item_missing:
$ref: '#/components/examples/errors/uri_error/item_missing'
no_payload:
$ref: '#/components/examples/errors/bad_request/no_payload'
'401':
description: Unauthorized
content:
@ -86,7 +89,8 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/uri_error/item_missing'
item_missing:
$ref: '#/components/examples/errors/uri_error/item_missing'
'401':
description: Unauthorized
content:
@ -118,6 +122,9 @@ components:
application/json:
schema:
$ref: '#/components/schemas/groups/get'
headers:
Location:
$ref: 'common.yaml#/components/headers/Location'
'400':
description: Bad request
content:
@ -125,8 +132,10 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/bad_request/no_payload'
- $ref: '#/components/examples/errors/database_error/duplicate'
no_payload:
$ref: '#/components/examples/errors/bad_request/no_payload'
duplicate:
$ref: '#/components/examples/errors/database_error/duplicate'
'401':
description: Unauthorized
content:
@ -161,7 +170,6 @@ components:
name:
description: Group name
type: string
required: true
example: test_group
comment:
type: object
@ -169,7 +177,6 @@ components:
comment:
description: User-provided free-text comment for this group (may be `null` if not specified)
type: string
required: false
nullable: true
default: null
example: Some comment for this group
@ -179,12 +186,10 @@ components:
enabled:
description: Status of item
type: boolean
required: false
default: true
example: true
readonly:
type: object
summary: Readonly properties of a single group
properties:
id:
description: Database ID
@ -203,7 +208,6 @@ components:
example: 1611239099
examples:
groups:
name: Example groups
value:
groups:
- name: "Default"

View File

@ -82,7 +82,6 @@ components:
required: false
schema:
type: integer
default: 100
- in: query
name: upstream
description: Filter by specific upstream

View File

@ -24,7 +24,8 @@ components:
schema:
$ref: '#/components/schemas/lists/get'
examples:
- $ref: '#/components/examples/lists'
lists:
$ref: '#/components/examples/lists'
'401':
description: Unauthorized
content:
@ -61,8 +62,10 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/uri_error/item_missing'
- $ref: '#/components/examples/errors/bad_request/no_payload'
item_missing:
$ref: '#/components/examples/errors/uri_error/item_missing'
no_payload:
$ref: '#/components/examples/errors/bad_request/no_payload'
'401':
description: Unauthorized
content:
@ -86,7 +89,8 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/uri_error/item_missing'
item_missing:
$ref: '#/components/examples/errors/uri_error/item_missing'
'401':
description: Unauthorized
content:
@ -124,6 +128,9 @@ components:
application/json:
schema:
$ref: '#/components/schemas/lists/get'
headers:
Location:
$ref: 'common.yaml#/components/headers/Location'
'400':
description: Bad request
content:
@ -131,8 +138,10 @@ components:
schema:
$ref: 'common.yaml#/components/errors/bad_request'
examples:
- $ref: '#/components/examples/errors/bad_request/no_payload'
- $ref: '#/components/examples/errors/database_error/duplicate'
no_payload:
$ref: '#/components/examples/errors/bad_request/no_payload'
duplicate:
$ref: '#/components/examples/errors/database_error/duplicate'
'401':
description: Unauthorized
content:
@ -170,7 +179,6 @@ components:
address:
description: Address of the list
type: string
required: true
example: https://hosts-file.net/ad_servers.txt
comment:
type: object
@ -178,7 +186,6 @@ components:
comment:
description: User-provided free-text comment for this list (may be `null` if not specified)
type: string
required: false
nullable: true
default: null
example: Some comment for this list
@ -189,7 +196,6 @@ components:
description: Array of group IDs
type: array
default: [0]
required: false
items:
type: integer
enabled:
@ -198,12 +204,10 @@ components:
enabled:
description: Status of domain
type: boolean
required: false
default: true
example: true
readonly:
type: object
summary: Readonly properties of a single list
properties:
id:
description: Database ID
@ -222,7 +226,6 @@ components:
example: 1611239099
examples:
lists:
name: Example lists
value:
lists:
- address: "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"

View File

@ -23,7 +23,7 @@ servers:
default: pi.hole
port:
description: Port of your Pi-hole's API
default: 8080
default: "8080"
path:
description: Path where your Pi-hole's API is hosted
default: api

View File

@ -32,7 +32,7 @@ components:
description: Number of blocked queries
example: 3465
percent_blocked:
type: float
type: number
description: Percent of blocked queries
example: 34.5
unique_domains:

View File

@ -0,0 +1,13 @@
const Enforcer = require('openapi-enforcer');
// JSON and YAML files accepted
Enforcer('src/api/docs/content/specs/main.yaml', { fullResult: true })
.then(function ({ error, warning }) {
if (!error && !warning) {
console.log('No errors with your document')
} else {
if(error) console.error(error)
if(warning) console.warn(warning);
process.exit(1);
}
})