@cryptotaxi247 / netdata-1 / commits / 7b3f17d32

Building a fuzzer against the API (issue #7163) (#7210)

New testing tool for the web API. We are calling this a "fuzzer" until a better name is suggested. This tool reads the swagger definitions of the API and parses the format of the requests and responses. The tool can generate randomized requests, which are sent to a netdata host, and then validate the json responses against the schema defined in the swagger. A traditional fuzzer only produces a single bit of information about each test (did the target system crash). This tool verifies that the call into the API produced a valid response structure, which produces more information about the correct functioning of the host. This current version performs a small sweep through the API calls as that is sufficient to find some incorrect response codes, and for testing the URL parser in the next issue (#7229) . A future update (in the next sprint) will add options to perform a deeper scan that brute-forces the parameter-space of the API, and combine it with our standard approach to stress-testing.

Andrew Moss committed Nov 4, 2019 at 09:52 UTC 7b3f17d32425a2671cb733c4053b49cf6aa96b1c
3 files changed +484 -336
tests/api/fuzzer.py new
+378
@@ -0,0 +1,378 @@
1 +import argparse
2 +import json
3 +import logging
4 +import posixpath
5 +import random
6 +import re
7 +import requests
8 +import string
9 +import sys
10 +import urllib.parse
11 +
12 +#######################################################################################################################
13 +# Utilities
14 +
15 +
16 +def some(s):
17 + return random.choice(sorted(s))
18 +
19 +
20 +def not_some(s):
21 + test_set = random.choice([string.ascii_uppercase + string.ascii_lowercase,
22 + string.digits,
23 + string.digits + ".E-",
24 + '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJK'
25 + 'LMNOPQRSTUVWXYZ!"#$%\'()*+,-./:;<=>?@[\\]^_`{|}~ '])
26 + test_len = random.choice([1, 2, 3, 37, 61, 121])
27 + while True:
28 + x = ''.join([random.choice(test_set) for _ in range(test_len)])
29 + if x not in s:
30 + return x
31 +
32 +
33 +def build_url(host_maybe_scheme, base_path):
34 + try:
35 + if '//' not in host_maybe_scheme:
36 + host_maybe_scheme = '//' + host_maybe_scheme
37 + url_tuple = urllib.parse.urlparse(host_maybe_scheme)
38 + if base_path[0] == '/':
39 + base_path = base_path[1:]
40 + return url_tuple.netloc, posixpath.join(url_tuple.path, base_path)
41 + except Exception as e:
42 + L.error(f"Critical failure decoding arguments -> {e}")
43 + sys.exit(-1)
44 +
45 +
46 +#######################################################################################################################
47 +# Data-model and processing
48 +
49 +
50 +class Param(object):
51 + def __init__(self, name, location, kind):
52 + self.location = location
53 + self.kind = kind
54 + self.name = name
55 + self.values = set()
56 +
57 + def dump(self):
58 + print(f"{self.name} in {self.location} is {self.kind} : {{{self.values}}}")
59 +
60 +
61 +def does_response_fit_schema(schema_path, schema, resp):
62 + '''The schema_path argument tells us where we are (globally) in the schema. The schema argument is the
63 + sub-tree within the schema json that we are validating against. The resp is the json subtree from the
64 + target host's response.
65 +
66 + The basic idea is this: swagger defines a model of valid json trees. In this sense it is a formal
67 + language and we can validate a given server response by checking if the language accepts a particular
68 + server response. This is basically a parser, but instead of strings we are operating on languages
69 + of trees.
70 +
71 + This could probably be extended to arbitrary swagger definitions - but the amount of work increases
72 + rapidly as we attempt to cover the full semantics of languages of trees defined in swagger. Instead
73 + we have some special cases that describe the parts of the semantics that we've used to describe the
74 + netdata API.
75 +
76 + If we hit an error (in the schema) that prevents further checks then we return early, otherwise we
77 + try to collect as many errors as possible.
78 + '''
79 + success = True
80 + if "type" not in schema:
81 + L.error(f"Cannot progress past {schema_path} -> no type specified in dictionary")
82 + print(json.dumps(schema, indent=2))
83 + return False
84 + if schema["type"] == "object":
85 + if isinstance(resp, dict) and "properties" in schema and isinstance(schema["properties"], dict):
86 + L.debug(f"Validate properties against dictionary at {schema_path}")
87 + for k, v in schema["properties"].items():
88 + L.debug(f"Validate {k} received with {v}")
89 + if v.get("required", False) and k not in resp:
90 + L.error(f"Missing {k} in response at {schema_path}")
91 + print(json.dumps(resp, indent=2))
92 + return False
93 + if k in resp:
94 + if not does_response_fit_schema(posixpath.join(schema_path, k), v, resp[k]):
95 + success = False
96 + elif isinstance(resp, dict) and "additionalProperties" in schema \
97 + and isinstance(schema["additionalProperties"], dict):
98 + kv_schema = schema["additionalProperties"]
99 + L.debug(f"Validate additionalProperties against every value in dictionary at {schema_path}")
100 + if "type" in kv_schema and kv_schema["type"] == "object":
101 + for k, v in resp.items():
102 + if not does_response_fit_schema(posixpath.join(schema_path, k), kv_schema, v):
103 + success = False
104 + else:
105 + L.error("Don't understand what the additionalProperties means (it has no type?)")
106 + return False
107 + else:
108 + L.error(f"Can't understand schema at {schema_path}")
109 + print(json.dumps(schema, indent=2))
110 + return False
111 + elif schema["type"] == "string":
112 + if isinstance(resp, str):
113 + L.debug(f"{repr(resp)} matches {repr(schema)} at {schema_path}")
114 + return True
115 + L.error(f"{repr(resp)} does not match schema {repr(schema)} at {schema_path}")
116 + return False
117 + elif schema["type"] == "boolean":
118 + if isinstance(resp, bool):
119 + L.debug(f"{repr(resp)} matches {repr(schema)} at {schema_path}")
120 + return True
121 + L.error(f"{repr(resp)} does not match schema {repr(schema)} at {schema_path}")
122 + return False
123 + elif schema["type"] == "number":
124 + if 'nullable' in schema and resp is None:
125 + L.debug(f"{repr(resp)} matches {repr(schema)} at {schema_path} (because nullable)")
126 + return True
127 + if isinstance(resp, int) or isinstance(resp, float):
128 + L.debug(f"{repr(resp)} matches {repr(schema)} at {schema_path}")
129 + return True
130 + L.error(f"{repr(resp)} does not match schema {repr(schema)} at {schema_path}")
131 + return False
132 + elif schema["type"] == "integer":
133 + if 'nullable' in schema and resp is None:
134 + L.debug(f"{repr(resp)} matches {repr(schema)} at {schema_path} (because nullable)")
135 + return True
136 + if isinstance(resp, int):
137 + L.debug(f"{repr(resp)} matches {repr(schema)} at {schema_path}")
138 + return True
139 + L.error(f"{repr(resp)} does not match schema {repr(schema)} at {schema_path}")
140 + return False
141 + elif schema["type"] == "array":
142 + if "items" not in schema:
143 + L.error(f"Schema for array at {schema_path} does not specify items!")
144 + return False
145 + item_schema = schema["items"]
146 + if not isinstance(resp, list):
147 + L.error(f"Server did not return a list for {schema_path} (typed as array in schema)")
148 + return False
149 + for i, item in enumerate(resp):
150 + if not does_response_fit_schema(posixpath.join(schema_path, str(i)), item_schema, item):
151 + success = False
152 + else:
153 + L.error(f"Invalid swagger type {schema['type']} for {type(resp)} at {schema_path}")
154 + print(json.dumps(schema, indent=2))
155 + return False
156 + return success
157 +
158 +
159 +class GetPath(object):
160 + def __init__(self, url, spec):
161 + self.url = url
162 + self.req_params = {}
163 + self.opt_params = {}
164 + self.success = None
165 + self.failures = {}
166 + if 'parameters' in spec.keys():
167 + for p in spec['parameters']:
168 + name = p['name']
169 + req = p.get('required', False)
170 + target = self.req_params if req else self.opt_params
171 + target[name] = Param(name, p['in'], p['type'])
172 + if 'default' in p:
173 + defs = p['default']
174 + if isinstance(defs, list):
175 + for d in defs:
176 + target[name].values.add(d)
177 + else:
178 + target[name].values.add(defs)
179 + if 'enum' in p:
180 + for v in p['enum']:
181 + target[name].values.add(v)
182 + if req and len(target[name].values) == 0:
183 + print(f"FAIL: No default values in swagger for required parameter {name} in {self.url}")
184 + for code, schema in spec['responses'].items():
185 + if code[0] == "2" and 'schema' in schema:
186 + self.success = schema['schema']
187 + elif code[0] == "2":
188 + L.error(f"2xx response with no schema in {self.url}")
189 + else:
190 + self.failures[code] = schema
191 +
192 + def generate_success(self, host):
193 + url_args = "&".join([f"{p.name}={some(p.values)}" for p in self.req_params.values()])
194 + base_url = urllib.parse.urljoin(host, self.url)
195 + test_url = f"{base_url}?{url_args}"
196 + if url_filter.match(test_url):
197 + try:
198 + resp = requests.get(url=test_url, verify=(not args.tls_no_verify))
199 + self.validate(test_url, resp, True)
200 + except Exception as e:
201 + L.error(f"Network failure in test {e}")
202 + else:
203 + L.debug(f"url_filter skips {test_url}")
204 +
205 + def generate_failure(self, host):
206 + all_params = list(self.req_params.values()) + list(self.opt_params.values())
207 + bad_param = ''.join([random.choice(string.ascii_lowercase) for _ in range(5)])
208 + while bad_param in all_params:
209 + bad_param = ''.join([random.choice(string.ascii_lowercase) for _ in range(5)])
210 + all_params.append(Param(bad_param, "query", "string"))
211 + url_args = "&".join([f"{p.name}={not_some(p.values)}" for p in all_params])
212 + base_url = urllib.parse.urljoin(host, self.url)
213 + test_url = f"{base_url}?{url_args}"
214 + if url_filter.match(test_url):
215 + try:
216 + resp = requests.get(url=test_url, verify=(not args.tls_no_verify))
217 + self.validate(test_url, resp, False)
218 + except Exception as e:
219 + L.error(f"Network failure in test {e}")
220 +
221 + def validate(self, test_url, resp, expect_success):
222 + try:
223 + resp_json = json.loads(resp.text)
224 + except json.decoder.JSONDecodeError as e:
225 + L.error(f"Non-json response from {test_url}")
226 + return
227 + success_code = resp.status_code >= 200 and resp.status_code < 300
228 + if success_code and expect_success:
229 + if self.success is not None:
230 + if does_response_fit_schema(posixpath.join(self.url, str(resp.status_code)), self.success, resp_json):
231 + L.info(f"tested {test_url}")
232 + else:
233 + L.error(f"tested {test_url}")
234 + else:
235 + L.error(f"Missing schema {test_url}")
236 + elif not success_code and not expect_success:
237 + schema = self.failures.get(str(resp.status_code), None)
238 + if schema is not None:
239 + if does_response_fit_schema(posixpath.join(self.url, str(resp.status_code)), schema, resp_json):
240 + L.info(f"tested {test_url}")
241 + else:
242 + L.error(f"tested {test_url}")
243 + else:
244 + L.error("Missing schema for {resp.status_code} from {test_url}")
245 + else:
246 + L.error(f"Received incorrect status code {resp.status_code} against {test_url}")
247 +
248 +
249 +def get_the_spec(url):
250 + if url[:7] == "file://":
251 + with open(url[7:]) as f:
252 + return f.read()
253 + return requests.get(url=url).text
254 +
255 +
256 +# Swagger paths look absolute but they are relative to the base.
257 +def not_absolute(path):
258 + return path[1:] if path[0] == '/' else path
259 +
260 +
261 +def find_ref(spec, path):
262 + if len(path) > 0 and path[0] == '#':
263 + return find_ref(spec, path[1:])
264 + if len(path) == 1:
265 + return spec[path[0]]
266 + return find_ref(spec[path[0]], path[1:])
267 +
268 +
269 +def resolve_refs(spec, spec_root=None):
270 + '''Find all "$ref" keys in the swagger spec and inline their target schemas.
271 +
272 + As with all inliners this will break if a definition recursively links to itself, but this should not
273 + happen in swagger as embedding a structure inside itself would produce a record of infinite size.'''
274 + if spec_root is None:
275 + spec_root = spec
276 + newspec = {}
277 + for k, v in spec.items():
278 + if k == "$ref":
279 + path = v.split('/')
280 + target = find_ref(spec_root, path)
281 + # Unfold one level of the tree and erase the $ref if possible.
282 + if isinstance(target, dict):
283 + for kk, vv in resolve_refs(target, spec_root).items():
284 + newspec[kk] = vv
285 + else:
286 + newspec[k] = target
287 + elif isinstance(v, dict):
288 + newspec[k] = resolve_refs(v, spec_root)
289 + else:
290 + newspec[k] = v
291 + # This is an artifact of inline the $refs when they are inside a properties key as their children should be
292 + # pushed up into the parent dictionary. They must be merged (union) rather than replace as we use this to
293 + # implement polymorphism in the data-model.
294 + if 'properties' in newspec and isinstance(newspec['properties'], dict) and \
295 + 'properties' in newspec['properties']:
296 + sub = newspec['properties']['properties']
297 + del newspec['properties']['properties']
298 + if 'type' in newspec['properties']:
299 + del newspec['properties']['type']
300 + for k, v in sub.items():
301 + newspec['properties'][k] = v
302 + return newspec
303 +
304 +
305 +#######################################################################################################################
306 +# Initialization
307 +
308 +random.seed(7) # Default is reproducible sequences
309 +
310 +parser = argparse.ArgumentParser()
311 +parser.add_argument('--url', type=str,
312 + default='https://raw.githubusercontent.com/netdata/netdata/master/web/api/netdata-swagger.json',
313 + help='The URL of the API definition in swagger. The default will pull the latest version '
314 + 'from the main branch.')
315 +parser.add_argument('--host', type=str,
316 + help='The URL of the target host to fuzz. The default will read the host from the swagger '
317 + 'definition.')
318 +parser.add_argument('--reseed', action='store_true',
319 + help="Pick a random seed for the PRNG. The default uses a constant seed for reproducibility.")
320 +parser.add_argument('--passes', action='store_true',
321 + help="Log information about tests that pass")
322 +parser.add_argument('--detail', action='store_true',
323 + help="Log information about the response/schema comparisons during each test")
324 +parser.add_argument('--filter', type=str,
325 + default=".*",
326 + help="Supply a regex used to filter the testing URLs generated")
327 +parser.add_argument('--tls-no-verify', action='store_true',
328 + help="Disable TLS certification verification to allow connection to hosts that use"
329 + "self-signed certificates")
330 +parser.add_argument('--dump-inlined', action='store_true',
331 + help='Dump the inlined swagger spec instead of fuzzing. For "reasons".')
332 +
333 +args = parser.parse_args()
334 +if args.reseed:
335 + random.seed()
336 +
337 +spec = json.loads(get_the_spec(args.url))
338 +inlined_spec = resolve_refs(spec)
339 +if args.dump_inlined:
340 + print(json.dumps(inlined_spec, indent=2))
341 + sys.exit(-1)
342 +
343 +logging.addLevelName(40, "FAIL")
344 +logging.addLevelName(20, "PASS")
345 +logging.addLevelName(10, "DETAIL")
346 +L = logging.getLogger()
347 +handler = logging.StreamHandler(sys.stdout)
348 +if not args.passes and not args.detail:
349 + L.setLevel(logging.ERROR)
350 +elif args.passes and not args.detail:
351 + L.setLevel(logging.INFO)
352 +elif args.detail:
353 + L.setLevel(logging.DEBUG)
354 +handler.setFormatter(logging.Formatter(fmt="%(levelname)s %(message)s"))
355 +L.addHandler(handler)
356 +
357 +url_filter = re.compile(args.filter)
358 +
359 +if spec['swagger'] != '2.0':
360 + L.error(f"Unexpected swagger version")
361 + sys.exit(-1)
362 +L.info(f"Fuzzing {spec['info']['title']} / {spec['info']['version']}")
363 +
364 +host, base_url = build_url(args.host or spec['host'], inlined_spec['basePath'])
365 +
366 +L.info(f"Target host is {base_url}")
367 +paths = []
368 +for name, p in inlined_spec['paths'].items():
369 + if 'get' in p:
370 + name = not_absolute(name)
371 + paths.append(GetPath(posixpath.join(base_url, name), p['get']))
372 + elif 'put' in p:
373 + L.error(f"Generation of PUT methods (for {name} is unimplemented")
374 +
375 +for s in inlined_spec['schemes']:
376 + for p in paths:
377 + resp = p.generate_success(s + "://" + host)
378 + resp = p.generate_failure(s+"://"+host)
web/api/netdata-swagger.json
+17 -30
@@ -40,10 +40,7 @@
40 "200": {
41 "description": "An array of charts.",
42 "schema": {
43 - "type": "array",
44 - "items": {
43 "$ref": "#/definitions/chart_summary"
46 - }
44 }
45 }
46 }
@@ -91,7 +88,8 @@
88 "description": "The id of the chart as returned by the /charts call.",
89 "required": true,
90 "type": "string",
94 - "format": "as returned by /charts"
91 + "format": "as returned by /charts",
92 + "default": "system.cpu"
93 }
94 ],
95 "responses": {
@@ -951,9 +949,7 @@
949 "type": "object",
950 "description": "An object containing all the chart objects available at the netdata server. This is used as an indexed array. The key of each chart object is the id of the chart.",
951 "properties": {
954 - "key": {
952 "$ref": "#/definitions/chart"
956 - }
953 }
954 },
955 "charts_count": {
@@ -998,7 +994,7 @@
994 "description": "The title of the chart."
995 },
996 "priority": {
1001 - "type": "string",
997 + "type": "number",
998 "description": "The relative priority of the chart. NetData does not care about priorities. This is just an indication of importance for the chart viewers to sort charts of higher priority (lower number) closer to the top. Priority sorting should only be used among charts of the same type or family."
999 },
1000 "enabled": {
@@ -1040,27 +1036,31 @@
1036 },
1037 "dimensions": {
1038 "type": "object",
1043 - "description": "An object containing all the chart dimensions available for the chart. This is used as an indexed array. The key of the object the id of the dimension.",
1044 - "properties": {
1045 - "key": {
1046 - "$ref": "#/definitions/dimension"
1039 + "description": "An object containing all the chart dimensions available for the chart. This is used as an indexed array. For each pair in the dictionary: the key is the id of the dimension and the value is a dictionary containing the name.",
1040 + "additionalProperties" : {
1041 + "type" : "object",
1042 + "properties" : {
1043 + "name" : {
1044 + "type" : "string",
1045 + "description" : "The name of the dimension"
1046 + }
1047 }
1048 }
1049 },
1050 "chart_variables": {
1051 "type": "object",
1052 "properties": {
1053 - "key": {
1053 "$ref": "#/definitions/chart_variables"
1055 - }
1054 }
1055 },
1056 "green": {
1057 "type": "number",
1058 + "nullable": "true",
1059 "description": "Chart health green threshold."
1060 },
1061 "red": {
1062 "type": "number",
1063 + "nullable": "true",
1064 "description": "Chart health red threshold."
1065 }
1066 }
@@ -1091,9 +1091,7 @@
1091 "chart_variables": {
1092 "type": "object",
1093 "properties": {
1094 - "key": {
1094 "$ref": "#/definitions/chart_variables"
1096 - }
1095 }
1096 },
1097 "family_variables": {
@@ -1137,15 +1135,6 @@
1135 }
1136 }
1137 },
1140 - "dimension": {
1141 - "type": "object",
1142 - "properties": {
1143 - "name": {
1144 - "type": "string",
1145 - "description": "The name of the dimension."
1146 - }
1147 - }
1148 - },
1138 "data": {
1139 "type": "object",
1140 "discriminator": "format",
@@ -1238,9 +1227,7 @@
1227 "chart_variables": {
1228 "type": "object",
1229 "properties": {
1241 - "key": {
1230 "$ref": "#/definitions/chart_variables"
1243 - }
1231 }
1232 }
1233 }
@@ -1678,12 +1665,12 @@
1665 "type": "string"
1666 },
1667 "value": {
1681 - "type": "string",
1682 - "format": "nullable"
1668 + "type": "number",
1669 + "nullable" : "true"
1670 },
1671 "old_value": {
1685 - "type": "string",
1686 - "format": "nullable"
1672 + "type": "number",
1673 + "nullable" : "true"
1674 }
1675 }
1676 }
web/api/netdata-swagger.yaml
+89 -306
@@ -35,16 +35,12 @@ paths:
35 /charts:
36 get:
37 summary: Get a list of all charts available at the server
38 - description: >-
39 - The charts endpoint returns a summary about all charts stored in the
40 - netdata server.
38 + description: The charts endpoint returns a summary about all charts stored in the netdata server.
39 responses:
40 '200':
41 description: An array of charts.
42 schema:
45 - type: array
46 - items:
47 - $ref: '#/definitions/chart_summary'
43 + $ref: '#/definitions/chart_summary'
44 /chart:
45 get:
46 summary: Get info about a specific chart
@@ -69,10 +65,7 @@ paths:
65 /alarm_variables:
66 get:
67 summary: List variables available to configure alarms for a chart
72 - description: >-
73 - Returns the basic information of a chart and all the variables that can
74 - be used in alarm and template health configurations for the particular
75 - chart or family.
68 + description: Returns the basic information of a chart and all the variables that can be used in alarm and template health configurations for the particular chart or family.
69 parameters:
70 - name: chart
71 in: query
@@ -80,11 +73,10 @@ paths:
73 required: true
74 type: string
75 format: as returned by /charts
76 + default: system.cpu
77 responses:
78 '200':
85 - description: >-
86 - A javascript object with information about the chart and the
87 - available variables.
79 + description: A javascript object with information about the chart and the available variables.
80 schema:
81 $ref: '#/definitions/alarm_variables'
82 '400':
@@ -92,15 +84,11 @@ paths:
84 '404':
85 description: No chart with the given id is found.
86 '500':
95 - description: >-
96 - Internal server error. This usually means the server is out of
97 - memory.
87 + description: Internal server error. This usually means the server is out of memory.
88 /data:
89 get:
90 summary: Get collected data for a specific chart
101 - description: >-
102 - The data endpoint returns data stored in the round robin database of a
103 - chart.
91 + description: The data endpoint returns data stored in the round robin database of a chart.
92 parameters:
93 - name: chart
94 in: query
@@ -112,10 +100,7 @@ paths:
100 default: system.cpu
101 - name: dimension
102 in: query
115 - description: >-
116 - Zero, one or more dimension ids or names, as returned by the /chart
117 - call, separated with comma or pipe. Netdata simple patterns are
118 - supported.
103 + description: 'Zero, one or more dimension ids or names, as returned by the /chart call, separated with comma or pipe. Netdata simple patterns are supported.'
104 required: false
105 type: array
106 items:
@@ -125,15 +110,7 @@ paths:
110 allowEmptyValue: false
111 - name: after
112 in: query
128 - description: >-
129 - This parameter can either be an absolute timestamp specifying the
130 - starting point of the data to be returned, or a relative number of
131 - seconds (negative, relative to parameter: before). Netdata will
132 - assume it is a relative number if it is less that 3 years (in
133 - seconds). Netdata will adapt this parameter to the boundaries of the
134 - round robin database. The default is the beginning of the round
135 - robin database (i.e. by default netdata will attempt to return data
136 - for the entire database).
113 + description: 'This parameter can either be an absolute timestamp specifying the starting point of the data to be returned, or a relative number of seconds (negative, relative to parameter: before). Netdata will assume it is a relative number if it is less that 3 years (in seconds). Netdata will adapt this parameter to the boundaries of the round robin database. The default is the beginning of the round robin database (i.e. by default netdata will attempt to return data for the entire database).'
114 required: true
115 type: number
116 format: integer
@@ -141,25 +118,14 @@ paths:
118 default: -600
119 - name: before
120 in: query
144 - description: >-
145 - This parameter can either be an absolute timestamp specifying the
146 - ending point of the data to be returned, or a relative number of
147 - seconds (negative), relative to the last collected timestamp.
148 - Netdata will assume it is a relative number if it is less than 3
149 - years (in seconds). Netdata will adapt this parameter to the
150 - boundaries of the round robin database. The default is zero (i.e.
151 - the timestamp of the last value collected).
121 + description: 'This parameter can either be an absolute timestamp specifying the ending point of the data to be returned, or a relative number of seconds (negative), relative to the last collected timestamp. Netdata will assume it is a relative number if it is less than 3 years (in seconds). Netdata will adapt this parameter to the boundaries of the round robin database. The default is zero (i.e. the timestamp of the last value collected).'
122 required: false
123 type: number
124 format: integer
125 default: 0
126 - name: points
127 in: query
158 - description: >-
159 - The number of points to be returned. If not given, or it is <= 0, or
160 - it is bigger than the points stored in the round robin database for
161 - this chart for the given duration, all the available collected
162 - values for the given duration will be returned.
128 + description: 'The number of points to be returned. If not given, or it is <= 0, or it is bigger than the points stored in the round robin database for this chart for the given duration, all the available collected values for the given duration will be returned.'
129 required: true
130 type: number
131 format: integer
@@ -167,13 +133,7 @@ paths:
133 default: 20
134 - name: group
135 in: query
170 - description: >-
171 - The grouping method. If multiple collected values are to be grouped
172 - in order to return fewer points, this parameters defines the method
173 - of grouping. methods supported "min", "max", "average", "sum",
174 - "incremental-sum". "max" is actually calculated on the absolute
175 - value collected (so it works for both positive and negative
176 - dimesions to return the most extreme value in either direction).
136 + description: 'The grouping method. If multiple collected values are to be grouped in order to return fewer points, this parameters defines the method of grouping. methods supported "min", "max", "average", "sum", "incremental-sum". "max" is actually calculated on the absolute value collected (so it works for both positive and negative dimesions to return the most extreme value in either direction).'
137 required: true
138 type: string
139 enum:
@@ -188,10 +148,7 @@ paths:
148 allowEmptyValue: false
149 - name: gtime
150 in: query
191 - description: >-
192 - The grouping number of seconds. This is used in conjunction with
193 - group=average to change the units of metrics (ie when the data is
194 - per-second, setting gtime=60 will turn them to per-minute).
151 + description: 'The grouping number of seconds. This is used in conjunction with group=average to change the units of metrics (ie when the data is per-second, setting gtime=60 will turn them to per-minute).'
152 required: false
153 type: number
154 format: integer
@@ -256,30 +213,19 @@ paths:
213 allowEmptyValue: true
214 - name: filename
215 in: query
259 - description: >-
260 - Add Content-Disposition: attachment; filename=<filename> header to
261 - the response, that will instruct the browser to save the response
262 - with the given filename.
216 + description: 'Add Content-Disposition: attachment; filename=<filename> header to the response, that will instruct the browser to save the response with the given filename.'
217 required: false
218 type: string
219 allowEmptyValue: true
220 - name: tqx
221 in: query
268 - description: >-
269 - [Google Visualization
270 - API](https://developers.google.com/chart/interactive/docs/dev/implementing_data_source?hl=en)
271 - formatted parameter.
222 + description: '[Google Visualization API](https://developers.google.com/chart/interactive/docs/dev/implementing_data_source?hl=en) formatted parameter.'
223 required: false
224 type: string
225 allowEmptyValue: true
226 responses:
227 '200':
277 - description: >-
278 - The call was successful. The response includes the data in the
279 - format requested. Swagger2.0 does not process the discriminator
280 - field to show polymorphism. The response will be one of the
281 - sub-types of the data-schema according to the chosen format, e.g.
282 - json -> data_json.
228 + description: 'The call was successful. The response includes the data in the format requested. Swagger2.0 does not process the discriminator field to show polymorphism. The response will be one of the sub-types of the data-schema according to the chosen format, e.g. json -> data_json.'
229 schema:
230 $ref: '#/definitions/data'
231 '400':
@@ -287,9 +233,7 @@ paths:
233 '404':
234 description: No chart with the given id is found.
235 '500':
290 - description: >-
291 - Internal server error. This usually means the server is out of
292 - memory.
236 + description: Internal server error. This usually means the server is out of memory.
237 /badge.svg:
238 get:
239 summary: Generate a SVG image for a chart (or dimension)
@@ -322,15 +266,7 @@ paths:
266 allowEmptyValue: false
267 - name: after
268 in: query
325 - description: >-
326 - This parameter can either be an absolute timestamp specifying the
327 - starting point of the data to be returned, or a relative number of
328 - seconds, to the last collected timestamp. Netdata will assume it is
329 - a relative number if it is smaller than the duration of the round
330 - robin database for this chart. So, if the round robin database is
331 - 3600 seconds, any value from -3600 to 3600 will trigger relative
332 - arithmetics. Netdata will adapt this parameter to the boundaries of
333 - the round robin database.
269 + description: 'This parameter can either be an absolute timestamp specifying the starting point of the data to be returned, or a relative number of seconds, to the last collected timestamp. Netdata will assume it is a relative number if it is smaller than the duration of the round robin database for this chart. So, if the round robin database is 3600 seconds, any value from -3600 to 3600 will trigger relative arithmetics. Netdata will adapt this parameter to the boundaries of the round robin database.'
270 required: true
271 type: number
272 format: integer
@@ -338,28 +274,14 @@ paths:
274 default: -600
275 - name: before
276 in: query
341 - description: >-
342 - This parameter can either be an absolute timestamp specifying the
343 - ending point of the data to be returned, or a relative number of
344 - seconds, to the last collected timestamp. Netdata will assume it is
345 - a relative number if it is smaller than the duration of the round
346 - robin database for this chart. So, if the round robin database is
347 - 3600 seconds, any value from -3600 to 3600 will trigger relative
348 - arithmetics. Netdata will adapt this parameter to the boundaries of
349 - the round robin database.
277 + description: 'This parameter can either be an absolute timestamp specifying the ending point of the data to be returned, or a relative number of seconds, to the last collected timestamp. Netdata will assume it is a relative number if it is smaller than the duration of the round robin database for this chart. So, if the round robin database is 3600 seconds, any value from -3600 to 3600 will trigger relative arithmetics. Netdata will adapt this parameter to the boundaries of the round robin database.'
278 required: false
279 type: number
280 format: integer
281 default: 0
282 - name: group
283 in: query
356 - description: >-
357 - The grouping method. If multiple collected values are to be grouped
358 - in order to return fewer points, this parameters defines the method
359 - of grouping. methods are supported "min", "max", "average", "sum",
360 - "incremental-sum". "max" is actually calculated on the absolute
361 - value collected (so it works for both positive and negative
362 - dimesions to return the most extreme value in either direction).
284 + description: 'The grouping method. If multiple collected values are to be grouped in order to return fewer points, this parameters defines the method of grouping. methods are supported "min", "max", "average", "sum", "incremental-sum". "max" is actually calculated on the absolute value collected (so it works for both positive and negative dimesions to return the most extreme value in either direction).'
285 required: true
286 type: string
287 enum:
@@ -414,29 +336,21 @@ paths:
336 allowEmptyValue: true
337 - name: value_color
338 in: query
417 - description: >-
418 - A color to be used for the background of the label. You can set
419 - multiple using a pipe with a condition each, like this:
420 - color<value|color>value|color:null The following operators are
421 - supported: >, <, >=, <=, =, :null (to check if no value exists).
339 + description: 'A color to be used for the background of the label. You can set multiple using a pipe with a condition each, like this: color<value|color>value|color:null The following operators are supported: >, <, >=, <=, =, :null (to check if no value exists).'
340 required: false
341 type: string
342 format: any text
343 allowEmptyValue: true
344 - name: multiply
345 in: query
428 - description: >-
429 - Multiply the value with this number for rendering it at the image
430 - (integer value required).
346 + description: Multiply the value with this number for rendering it at the image (integer value required).
347 required: false
348 type: number
349 format: integer
350 allowEmptyValue: true
351 - name: divide
352 in: query
437 - description: >-
438 - Divide the value with this number for rendering it at the image
439 - (integer value required).
353 + description: Divide the value with this number for rendering it at the image (integer value required).
354 required: false
355 type: number
356 format: integer
@@ -456,15 +370,11 @@ paths:
370 '404':
371 description: No chart with the given id is found.
372 '500':
459 - description: >-
460 - Internal server error. This usually means the server is out of
461 - memory.
373 + description: Internal server error. This usually means the server is out of memory.
374 /allmetrics:
375 get:
376 summary: Get a value of all the metrics maintained by netdata
465 - description: >-
466 - The allmetrics endpoint returns the latest value of all charts and
467 - dimensions stored in the netdata server.
377 + description: The allmetrics endpoint returns the latest value of all charts and dimensions stored in the netdata server.
378 parameters:
379 - name: format
380 in: query
@@ -506,10 +416,7 @@ paths:
416 default: 'yes'
417 - name: names
418 in: query
509 - description: >-
510 - When enabled netdata will report dimension names. When disabled
511 - netdata will report dimension IDs. The default is controlled in
512 - netdata.conf.
419 + description: When enabled netdata will report dimension names. When disabled netdata will report dimension IDs. The default is controlled in netdata.conf.
420 required: false
421 type: string
422 enum:
@@ -518,10 +425,7 @@ paths:
425 default: 'yes'
426 - name: oldunits
427 in: query
521 - description: >-
522 - When enabled, netdata will show metric names for the default
523 - source=average as they appeared before 1.12, by using the legacy
524 - unit naming conventions.
428 + description: 'When enabled, netdata will show metric names for the default source=average as they appeared before 1.12, by using the legacy unit naming conventions.'
429 required: false
430 type: string
431 enum:
@@ -530,9 +434,7 @@ paths:
434 default: 'yes'
435 - name: hideunits
436 in: query
533 - description: >-
534 - When enabled, netdata will not include the units in the metric
535 - names, for the default source=average.
437 + description: 'When enabled, netdata will not include the units in the metric names, for the default source=average.'
438 required: false
439 type: string
440 enum:
@@ -541,9 +443,7 @@ paths:
443 default: 'yes'
444 - name: server
445 in: query
544 - description: >-
545 - Set a distinct name of the client querying prometheus metrics.
546 - Netdata will use the client IP if this is not set.
446 + description: Set a distinct name of the client querying prometheus metrics. Netdata will use the client IP if this is not set.
447 required: false
448 type: string
449 format: any text
@@ -555,9 +455,7 @@ paths:
455 format: any text
456 - name: data
457 in: query
558 - description: >-
559 - Select the prometheus response data source. There is a setting in
560 - netdata.conf for the default.
458 + description: Select the prometheus response data source. There is a setting in netdata.conf for the default.
459 required: false
460 type: string
461 enum:
@@ -573,11 +471,7 @@ paths:
471 /alarms:
472 get:
473 summary: Get a list of active or raised alarms on the server
576 - description: >-
577 - The alarms endpoint returns the list of all raised or enabled alarms on
578 - the netdata server. Called without any parameters, the raised alarms in
579 - state WARNING or CRITICAL are returned. By passing "?all", all the
580 - enabled alarms are returned.
474 + description: 'The alarms endpoint returns the list of all raised or enabled alarms on the netdata server. Called without any parameters, the raised alarms in state WARNING or CRITICAL are returned. By passing "?all", all the enabled alarms are returned.'
475 parameters:
476 - name: all
477 in: query
@@ -593,18 +487,11 @@ paths:
487 /alarm_log:
488 get:
489 summary: Retrieves the entries of the alarm log
596 - description: >-
597 - Returns an array of alarm_log entries, with historical information on
598 - raised and cleared alarms.
490 + description: 'Returns an array of alarm_log entries, with historical information on raised and cleared alarms.'
491 parameters:
492 - name: after
493 in: query
602 - description: >-
603 - Passing the parameter after=UNIQUEID returns all the events in the
604 - alarm log that occurred after UNIQUEID. An automated series of calls
605 - would call the interface once without after=, store the last
606 - UNIQUEID of the returned set, and give it back to get incrementally
607 - the next events.
494 + description: 'Passing the parameter after=UNIQUEID returns all the events in the alarm log that occurred after UNIQUEID. An automated series of calls would call the interface once without after=, store the last UNIQUEID of the returned set, and give it back to get incrementally the next events.'
495 required: false
496 type: integer
497 responses:
@@ -617,9 +504,7 @@ paths:
504 /alarm_count:
505 get:
506 summary: Get an overall status of the chart
620 - description: >-
621 - Checks multiple charts with the same context and counts number of alarms
622 - with given status.
507 + description: Checks multiple charts with the same context and counts number of alarms with given status.
508 parameters:
509 - in: query
510 name: context
@@ -649,40 +534,21 @@ paths:
534 default: RAISED
535 responses:
536 '200':
652 - description: >-
653 - An object containing a count of alarms with given status for given
654 - contexts.
537 + description: An object containing a count of alarms with given status for given contexts.
538 schema:
539 type: array
540 items:
541 type: number
542 '500':
660 - description: >-
661 - Internal server error. This usually means the server is out of
662 - memory.
543 + description: Internal server error. This usually means the server is out of memory.
544 /manage/health:
545 get:
665 - summary: >-
666 - Accesses the health management API to control health checks and
667 - notifications at runtime.
668 - description: >-
669 - Available from Netdata v1.12 and above, protected via bearer
670 - authorization. Especially useful for maintenance periods, the API allows
671 - you to disable health checks completely, silence alarm notifications, or
672 - Disable/Silence specific alarms that match selectors on alarm/template
673 - name, chart, context, host and family. For the simple disable/silence
674 - all scenaria, only the cmd parameter is required. The other parameters
675 - are used to define alarm selectors. For more information and examples,
676 - refer to the netdata documentation.
546 + summary: Accesses the health management API to control health checks and notifications at runtime.
547 + description: 'Available from Netdata v1.12 and above, protected via bearer authorization. Especially useful for maintenance periods, the API allows you to disable health checks completely, silence alarm notifications, or Disable/Silence specific alarms that match selectors on alarm/template name, chart, context, host and family. For the simple disable/silence all scenaria, only the cmd parameter is required. The other parameters are used to define alarm selectors. For more information and examples, refer to the netdata documentation.'
548 parameters:
549 - name: cmd
550 in: query
680 - description: >-
681 - DISABLE ALL: No alarm criteria are evaluated, nothing is written in
682 - the alarm log. SILENCE ALL: No notifications are sent. RESET: Return
683 - to the default state. DISABLE/SILENCE: Set the mode to be used for
684 - the alarms matching the criteria of the alarm selectors. LIST: Show
685 - active configuration.
551 + description: 'DISABLE ALL: No alarm criteria are evaluated, nothing is written in the alarm log. SILENCE ALL: No notifications are sent. RESET: Return to the default state. DISABLE/SILENCE: Set the mode to be used for the alarms matching the criteria of the alarm selectors. LIST: Show active configuration.'
552 required: false
553 type: string
554 enum:
@@ -694,21 +560,15 @@ paths:
560 - LIST
561 - name: alarm
562 in: query
697 - description: >-
698 - The expression provided will match both `alarm` and `template`
699 - names.
563 + description: The expression provided will match both `alarm` and `template` names.
564 type: string
565 - name: chart
566 in: query
703 - description: >-
704 - Chart ids/names, as shown on the dashboard. These will match the
705 - `on` entry of a configured `alarm`.
567 + description: 'Chart ids/names, as shown on the dashboard. These will match the `on` entry of a configured `alarm`.'
568 type: string
569 - name: context
570 in: query
709 - description: >-
710 - Chart context, as shown on the dashboard. These will match the `on`
711 - entry of a configured `template`.
571 + description: 'Chart context, as shown on the dashboard. These will match the `on` entry of a configured `template`.'
572 type: string
573 - name: hosts
574 in: query
@@ -847,26 +707,18 @@ definitions:
707 - freebsd
708 history:
709 type: number
850 - description: >-
851 - The duration, in seconds, of the round robin database maintained by
852 - netdata.
710 + description: 'The duration, in seconds, of the round robin database maintained by netdata.'
711 memory_mode:
712 type: string
713 description: The name of the database memory mode on the server.
714 update_every:
715 type: number
858 - description: >-
859 - The default update frequency of the netdata server. All charts have an
860 - update frequency equal or bigger than this.
716 + description: The default update frequency of the netdata server. All charts have an update frequency equal or bigger than this.
717 charts:
718 type: object
863 - description: >-
864 - An object containing all the chart objects available at the netdata
865 - server. This is used as an indexed array. The key of each chart object
866 - is the id of the chart.
719 + description: An object containing all the chart objects available at the netdata server. This is used as an indexed array. The key of each chart object is the id of the chart.
720 properties:
868 - key:
869 - $ref: '#/definitions/chart'
721 + $ref: '#/definitions/chart'
722 charts_count:
723 type: number
724 description: The number of charts.
@@ -890,39 +742,25 @@ definitions:
742 description: The name of the chart.
743 type:
744 type: string
893 - description: >-
894 - The type of the chart. Types are not handled by netdata. You can use
895 - this field for anything you like.
745 + description: The type of the chart. Types are not handled by netdata. You can use this field for anything you like.
746 family:
747 type: string
898 - description: >-
899 - The family of the chart. Families are not handled by netdata. You can
900 - use this field for anything you like.
748 + description: The family of the chart. Families are not handled by netdata. You can use this field for anything you like.
749 title:
750 type: string
751 description: The title of the chart.
752 priority:
905 - type: string
906 - description: >-
907 - The relative priority of the chart. NetData does not care about
908 - priorities. This is just an indication of importance for the chart
909 - viewers to sort charts of higher priority (lower number) closer to the
910 - top. Priority sorting should only be used among charts of the same
911 - type or family.
753 + type: number
754 + description: The relative priority of the chart. NetData does not care about priorities. This is just an indication of importance for the chart viewers to sort charts of higher priority (lower number) closer to the top. Priority sorting should only be used among charts of the same type or family.
755 enabled:
756 type: boolean
914 - description: >-
915 - True when the chart is enabled. Disabled charts do not currently
916 - collect values, but they may have historical values available.
757 + description: 'True when the chart is enabled. Disabled charts do not currently collect values, but they may have historical values available.'
758 units:
759 type: string
760 description: The unit of measurement for the values of all dimensions of the chart.
761 data_url:
762 type: string
922 - description: >-
923 - The absolute path to get data values for this chart. You are expected
924 - to use this path as the base when constructing the URL to fetch data
925 - values for this chart.
763 + description: The absolute path to get data values for this chart. You are expected to use this path as the base when constructing the URL to fetch data values for this chart.
764 chart_type:
765 type: string
766 description: The chart type.
@@ -932,41 +770,36 @@ definitions:
770 - stacked
771 duration:
772 type: number
935 - description: >-
936 - The duration, in seconds, of the round robin database maintained by
937 - netdata.
773 + description: 'The duration, in seconds, of the round robin database maintained by netdata.'
774 first_entry:
775 type: number
940 - description: >-
941 - The UNIX timestamp of the first entry (the oldest) in the round robin
942 - database.
776 + description: The UNIX timestamp of the first entry (the oldest) in the round robin database.
777 last_entry:
778 type: number
779 description: The UNIX timestamp of the latest entry in the round robin database.
780 update_every:
781 type: number
948 - description: >-
949 - The update frequency of this chart, in seconds. One value every this
950 - amount of time is kept in the round robin database.
782 + description: 'The update frequency of this chart, in seconds. One value every this amount of time is kept in the round robin database.'
783 dimensions:
784 type: object
953 - description: >-
954 - An object containing all the chart dimensions available for the chart.
955 - This is used as an indexed array. The key of the object the id of the
956 - dimension.
957 - properties:
958 - key:
959 - $ref: '#/definitions/dimension'
785 + description: 'An object containing all the chart dimensions available for the chart. This is used as an indexed array. For each pair in the dictionary: the key is the id of the dimension and the value is a dictionary containing the name.'
786 + additionalProperties:
787 + type: object
788 + properties:
789 + name:
790 + type: string
791 + description: The name of the dimension
792 chart_variables:
793 type: object
794 properties:
963 - key:
964 - $ref: '#/definitions/chart_variables'
795 + $ref: '#/definitions/chart_variables'
796 green:
797 type: number
798 + nullable: 'true'
799 description: Chart health green threshold.
800 red:
801 type: number
802 + nullable: 'true'
803 description: Chart health red threshold.
804 alarm_variables:
805 type: object
@@ -979,9 +812,7 @@ definitions:
812 description: The name of the chart.
813 cnart_context:
814 type: string
982 - description: >-
983 - The context of the chart. It is shared across multiple monitored
984 - software or hardware instances and used in alarm templates.
815 + description: The context of the chart. It is shared across multiple monitored software or hardware instances and used in alarm templates.
816 family:
817 type: string
818 description: The family of the chart.
@@ -991,8 +822,7 @@ definitions:
822 chart_variables:
823 type: object
824 properties:
994 - key:
995 - $ref: '#/definitions/chart_variables'
825 + $ref: '#/definitions/chart_variables'
826 family_variables:
827 type: object
828 properties:
@@ -1020,18 +850,10 @@ definitions:
850 varname2:
851 type: number
852 format: float
1023 - dimension:
1024 - type: object
1025 - properties:
1026 - name:
1027 - type: string
1028 - description: The name of the dimension.
853 data:
854 type: object
855 discriminator: format
1032 - description: >-
1033 - Response will contain the appropriate subtype, e.g. data_json depending on
1034 - the requested format.
856 + description: 'Response will contain the appropriate subtype, e.g. data_json depending on the requested format.'
857 properties:
858 api:
859 type: number
@@ -1044,44 +866,28 @@ definitions:
866 description: The name of the chart.
867 update_every:
868 type: number
1047 - description: >-
1048 - The update frequency of this chart, in seconds. One value every this
1049 - amount of time is kept in the round robin database (indepedently of
1050 - the current view).
869 + description: 'The update frequency of this chart, in seconds. One value every this amount of time is kept in the round robin database (indepedently of the current view).'
870 view_update_every:
871 type: number
1053 - description: >-
1054 - The current view appropriate update frequency of this chart, in
1055 - seconds. There is no point to request chart refreshes, using the same
1056 - settings, more frequently than this.
872 + description: 'The current view appropriate update frequency of this chart, in seconds. There is no point to request chart refreshes, using the same settings, more frequently than this.'
873 first_entry:
874 type: number
1059 - description: >-
1060 - The UNIX timestamp of the first entry (the oldest) in the round robin
1061 - database (indepedently of the current view).
875 + description: The UNIX timestamp of the first entry (the oldest) in the round robin database (indepedently of the current view).
876 last_entry:
877 type: number
1064 - description: >-
1065 - The UNIX timestamp of the latest entry in the round robin database
1066 - (indepedently of the current view).
878 + description: The UNIX timestamp of the latest entry in the round robin database (indepedently of the current view).
879 after:
880 type: number
1069 - description: >-
1070 - The UNIX timestamp of the first entry (the oldest) returned in this
1071 - response.
881 + description: The UNIX timestamp of the first entry (the oldest) returned in this response.
882 before:
883 type: number
884 description: The UNIX timestamp of the latest entry returned in this response.
885 min:
886 type: number
1077 - description: >-
1078 - The minimum value returned in the current view. This can be used to
1079 - size the y-series of the chart.
887 + description: The minimum value returned in the current view. This can be used to size the y-series of the chart.
888 max:
889 type: number
1082 - description: >-
1083 - The maximum value returned in the current view. This can be used to
1084 - size the y-series of the chart.
890 + description: The maximum value returned in the current view. This can be used to size the y-series of the chart.
891 dimension_names:
892 description: The dimension names of the chart as returned in the current view.
893 type: array
@@ -1093,9 +899,7 @@ definitions:
899 items:
900 type: string
901 latest_values:
1096 - description: >-
1097 - The latest values collected for the chart (indepedently of the current
1098 - view).
902 + description: The latest values collected for the chart (indepedently of the current view).
903 type: array
904 items:
905 type: string
@@ -1116,8 +920,7 @@ definitions:
920 chart_variables:
921 type: object
922 properties:
1119 - key:
1120 - $ref: '#/definitions/chart_variables'
923 + $ref: '#/definitions/chart_variables'
924 data_json:
925 description: Data response in json format.
926 allOf:
@@ -1132,18 +935,13 @@ definitions:
935 items:
936 type: string
937 data:
1135 - description: >-
1136 - The data requested, one element per sample with each element
1137 - containing the values of the dimensions described in the
1138 - labels value.
938 + description: 'The data requested, one element per sample with each element containing the values of the dimensions described in the labels value.'
939 type: array
940 items:
941 type: number
942 description: 'The result requested, in the format requested.'
943 data_flat:
1144 - description: >-
1145 - Data response in csv / tsv / tsv-excel / ssv / ssv-comma / markdown / html
1146 - formats.
944 + description: Data response in csv / tsv / tsv-excel / ssv / ssv-comma / markdown / html formats.
945 allOf:
946 - $ref: '#/definitions/data'
947 - properties:
@@ -1164,18 +962,13 @@ definitions:
962 - $ref: '#/definitions/data'
963 - properties:
964 result:
1167 - description: >-
1168 - The first inner array contains strings showing the labels of each
1169 - column, each subsequent array contains the values for each point
1170 - in time.
965 + description: 'The first inner array contains strings showing the labels of each column, each subsequent array contains the values for each point in time.'
966 type: array
967 items:
968 type: array
969 items: {}
970 data_datatable:
1176 - description: >-
1177 - Data response in datatable / datasource formats (suitable for Google
1178 - Charts).
971 + description: Data response in datatable / datasource formats (suitable for Google Charts).
972 allOf:
973 - $ref: '#/definitions/data'
974 - properties:
@@ -1212,11 +1005,7 @@ definitions:
1005 items:
1006 properties:
1007 v:
1215 - description: >-
1216 - Each value in the row is represented by an object
1217 - named `c` with five v fields: data, null, null, 0,
1218 - the value. This format is fixed by the Google
1219 - Charts API.
1008 + description: 'Each value in the row is represented by an object named `c` with five v fields: data, null, null, 0, the value. This format is fixed by the Google Charts API.'
1009 alarms:
1010 type: object
1011 properties:
@@ -1248,19 +1037,13 @@ definitions:
1037 type: string
1038 active:
1039 type: boolean
1251 - description: >-
1252 - Will be false only if the alarm is disabled in the
1253 - configuration.
1040 + description: Will be false only if the alarm is disabled in the configuration.
1041 disabled:
1042 type: boolean
1256 - description: >-
1257 - Whether the health check for this alarm has been disabled via
1258 - a health command API DISABLE command.
1043 + description: Whether the health check for this alarm has been disabled via a health command API DISABLE command.
1044 silenced:
1045 type: boolean
1261 - description: >-
1262 - Whether notifications for this alarm have been silenced via a
1263 - health command API SILENCE command.
1046 + description: Whether notifications for this alarm have been silenced via a health command API SILENCE command.
1047 exec:
1048 type: string
1049 recipient:
@@ -1425,8 +1208,8 @@ definitions:
1208 info:
1209 type: string
1210 value:
1428 - type: string
1429 - format: nullable
1211 + type: number
1212 + nullable: 'true'
1213 old_value:
1431 - type: string
1432 - format: nullable
1214 + type: number
1215 + nullable: 'true'