diff options
author | Costa Tsaousis <costa@netdata.cloud> | 2024-01-12 03:09:05 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-12 01:09:05 +0000 |
commit | 7fce3dcd9cb9eb87509a9cec80e51fefd0a971ff (patch) | |
tree | 7d77b663a540429d2da81bfafc392f7549cac24a | |
parent | 1474b502b871325e520f08af40c34036df017117 (diff) |
/api/v1/config tree improvements and swagger documentation (#16764)
-rw-r--r-- | daemon/config/dyncfg-tree.c | 20 | ||||
-rw-r--r-- | web/api/netdata-swagger.json | 355 | ||||
-rw-r--r-- | web/api/netdata-swagger.yaml | 225 | ||||
-rw-r--r-- | web/api/web_api_v1.c | 3 |
4 files changed, 591 insertions, 12 deletions
diff --git a/daemon/config/dyncfg-tree.c b/daemon/config/dyncfg-tree.c index 2155e4a771..086b1f13a3 100644 --- a/daemon/config/dyncfg-tree.c +++ b/daemon/config/dyncfg-tree.c @@ -21,6 +21,10 @@ static void dyncfg_to_json(DYNCFG *df, const char *id, BUFFER *wb) { buffer_json_member_add_object(wb, id); { buffer_json_member_add_string(wb, "type", dyncfg_id2type(df->type)); + + if(df->type == DYNCFG_TYPE_JOB) + buffer_json_member_add_string(wb, "template", string2str(df->template)); + buffer_json_member_add_string(wb, "status", dyncfg_id2status(df->status)); dyncfg_cmds2json_array(df->cmds, "cmds", wb); buffer_json_member_add_string(wb, "source_type", dyncfg_id2source_type(df->source_type)); @@ -46,13 +50,17 @@ static void dyncfg_to_json(DYNCFG *df, const char *id, BUFFER *wb) { buffer_json_object_close(wb); } -static void dyncfg_tree_for_host(RRDHOST *host, BUFFER *wb, const char *parent, const char *id __maybe_unused) { +static void dyncfg_tree_for_host(RRDHOST *host, BUFFER *wb, const char *path, const char *id) { size_t entries = dictionary_entries(dyncfg_globals.nodes); size_t used = 0; const DICTIONARY_ITEM *items[entries]; size_t restart_required = 0, plugin_rejected = 0, status_incomplete = 0, status_failed = 0; - size_t parent_len = strlen(parent); + STRING *template = NULL; + if(id && *id) + template = string_strdupz(id); + + size_t path_len = strlen(path); DYNCFG *df; dfe_start_read(dyncfg_globals.nodes, df) { if(!df->host) { @@ -60,17 +68,21 @@ static void dyncfg_tree_for_host(RRDHOST *host, BUFFER *wb, const char *parent, df->host = host; } - if(df->host != host || strncmp(string2str(df->path), parent, parent_len) != 0) + if(df->host != host || strncmp(string2str(df->path), path, path_len) != 0) continue; if(!rrd_function_available(host, string2str(df->function))) df->status = DYNCFG_STATUS_ORPHAN; + if((id && strcmp(id, df_dfe.name) != 0) || (template && df->template != template)) + continue; + items[used++] = dictionary_acquired_item_dup(dyncfg_globals.nodes, df_dfe.item); } dfe_done(df); - qsort(items, used, sizeof(const DICTIONARY_ITEM *), dyncfg_tree_compar); + if(used > 1) + qsort(items, used, sizeof(const DICTIONARY_ITEM *), dyncfg_tree_compar); buffer_flush(wb); buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_MINIFY); diff --git a/web/api/netdata-swagger.json b/web/api/netdata-swagger.json index 6ed3e08b8c..eee8af3306 100644 --- a/web/api/netdata-swagger.json +++ b/web/api/netdata-swagger.json @@ -373,6 +373,201 @@ } } }, + "/api/v1/config": { + "get": { + "operationId": "getConfig", + "tags": [ + "dyncfg" + ], + "description": "Get dynamic configuration information.\n", + "parameters": [ + { + "name": "action", + "in": "query", + "description": "The type of information required", + "schema": { + "type": "string", + "enum": [ + "tree", + "schema", + "get", + "enable", + "disable", + "restart" + ], + "default": "tree" + } + }, + { + "name": "id", + "in": "query", + "description": "The ID of the dynamic configuration entity", + "schema": { + "type": "string" + } + }, + { + "name": "path", + "in": "query", + "description": "Top level path of the configuration entities, used with action 'tree'", + "schema": { + "type": "string", + "default": "/" + } + }, + { + "name": "timeout", + "in": "query", + "description": "The timeout in seconds", + "schema": { + "type": "number", + "default": 120 + } + } + ], + "responses": { + "200": { + "description": "The call was successful.", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/config_default_response" + }, + { + "$ref": "#/components/schemas/config_tree" + }, + { + "$ref": "#/components/schemas/config_schema" + } + ] + } + } + } + }, + "400": { + "description": "Something is wrong with the request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/config_default_response" + } + } + } + }, + "404": { + "description": "The configurable entity requests is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/config_default_response" + } + } + } + } + } + }, + "post": { + "operationId": "postConfig", + "tags": [ + "dyncfg" + ], + "description": "Post dynamic configuration to Netdata.\n", + "parameters": [ + { + "name": "action", + "in": "query", + "description": "The type of action required.", + "schema": { + "type": "string", + "enum": [ + "add", + "test", + "update" + ] + } + }, + { + "name": "id", + "in": "query", + "description": "The ID of the dynamic configuration entity to configure.", + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the dynamic configuration entity, used with action 'add'", + "schema": { + "type": "string" + } + }, + { + "name": "timeout", + "in": "query", + "description": "The timeout in seconds", + "schema": { + "type": "number", + "default": 120 + } + } + ], + "responses": { + "200": { + "description": "The call was successful. This also means the configuration is currently running.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/config_default_response" + } + } + } + }, + "202": { + "description": "The call was successful. The configuration has been accepted, but its status is not yet known.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/config_default_response" + } + } + } + }, + "299": { + "description": "The call was successful. The configuration has been accepted, but a restart is required to apply it.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/config_default_response" + } + } + } + }, + "400": { + "description": "Something is wrong with the request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/config_default_response" + } + } + } + }, + "404": { + "description": "The configurable entity requests is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/config_default_response" + } + } + } + } + } + } + }, "/api/v2/data": { "get": { "operationId": "dataQuery2", @@ -385,7 +580,7 @@ { "name": "group_by", "in": "query", - "description": "A comma separated list of the groupings required.\nAll possible values can be combined together, except `selected`. If `selected` is given in the list, all others are ignored.\nThe order they are placed in the list is currently ignored.\n", + "description": "A comma separated list of the groupings required.\nAll possible values can be combined together, except `selected`. If `selected` is given in the list, all others are ignored.\nThe order they are placed in the list is currently ignored.\nThis parameter is also accepted as `group_by[0]` and `group_by[1]` when multiple grouping passes are required.\n", "required": false, "schema": { "type": "array", @@ -410,7 +605,7 @@ { "name": "group_by_label", "in": "query", - "description": "A comma separated list of the label keys to group by their values. The order of the labels in the list is respected.\n", + "description": "A comma separated list of the label keys to group by their values. The order of the labels in the list is respected.\nThis parameter is also accepted as `group_by_label[0]` and `group_by_label[1]` when multiple grouping passes are required.\n", "required": false, "schema": { "type": "string", @@ -421,7 +616,7 @@ { "name": "aggregation", "in": "query", - "description": "The aggregation function to apply when grouping metrics together.\nWhen option `raw` is given, `average` and `avg` behave like `sum` and the caller is expected to calculate the average.\n", + "description": "The aggregation function to apply when grouping metrics together.\nWhen option `raw` is given, `average` and `avg` behave like `sum` and the caller is expected to calculate the average.\nThis parameter is also accepted as `aggregation[0]` and `aggregation[1]` when multiple grouping passes are required.\n", "required": false, "schema": { "type": "string", @@ -430,7 +625,8 @@ "max", "avg", "average", - "sum" + "sum", + "percentage" ], "default": "average" } @@ -3689,8 +3885,11 @@ "type": "integer" }, "count": { - "description": "The number of metrics aggregated into this point. This exists only when the option `raw` is given to the query.\n", + "description": "The number of metrics aggregated into this point.\nThis exists only when the option `raw` is given to the query and the final aggregation point is NOT `percentage`.\n", "type": "integer" + }, + "hidden": { + "description": "The sum of the non-selected dimensions aggregated for this group item point.\nThis exists only when the option `raw` is given to the query and the final aggregation method is `percentage`.\n" } } }, @@ -4415,7 +4614,151 @@ }, "weighted_dimension": { "type": "number" + }, + "config_schema": { + "type": "object", + "properties": { + "jsonSchema": { + "type": "object", + "description": "Standard JSON Schema object describing the schema of each configurable entity." + }, + "uiSchema": { + "type": "object", + "description": "Schema for react-json-schema-form to drive the UI. Provides additional UI-specific configuration." + } + } + }, + "config_tree": { + "type": "object", + "properties": { + "version": { + "type": "integer", + "description": "The version of dynamic configuration supported by the Netdata agent." + }, + "tree": { + "type": "object", + "description": "A map of configuration entity paths, each containing one or more configurable entities.", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/config_entity" + } + } + }, + "attention": { + "$ref": "#/components/schemas/config_attention" + } + } + }, + "config_entity": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Can be 'single' for entities appearing once, 'template' for entities supporting multiple instances, or 'job' for jobs belonging to a template." + }, + "status": { + "type": "string", + "description": "The current status of the entity. Values include 'accepted', 'running', 'failed', 'disabled', 'incomplete', or 'orphan'." + }, + "cmds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of the possible actions supported by this entity." + }, + "source_type": { + "type": "string", + "description": "The source type of the configuration (e.g., 'internal', 'stock', 'user', 'discovered', 'dyncfg')." + }, + "source": { + "type": "string", + "description": "Additional information about the source, formatted as comma-separated name-value pairs." + }, + "sync": { + "type": "boolean", + "description": "Indicates if this is an internal module (true) or an external plugin (false)." + }, + "user_disabled": { + "type": "boolean", + "description": "True if the entity is disabled by the user." + }, + "restart_required": { + "type": "boolean", + "description": "True if the entity requires a restart after addition or update." + }, + "plugin_rejected": { + "type": "boolean", + "description": "True if a previously saved configuration failed to apply after a restart." + }, + "payload": { + "type": "object", + "description": "Object containing at least an 'available' boolean indicating if there's a saved configuration for this entity.", + "properties": { + "available": { + "type": "boolean" + } + } + }, + "saves": { + "type": "integer", + "description": "The number of times this configuration has been saved to disk by the dynamic configuration manager." + }, + "created_ut": { + "type": "integer", + "format": "int64", + "description": "The timestamp in microseconds when this dynamic configuration was first created." + }, + "modified_ut": { + "type": "integer", + "format": "int64", + "description": "The timestamp in microseconds when this dynamic configuration was last modified." + }, + "template": { + "type": "string", + "description": "Shows the template the job belongs to, applicable when type is 'job'." + } + } + }, + "config_attention": { + "type": "object", + "properties": { + "degraded": { + "type": "boolean" + }, + "restart_required": { + "type": "integer" + }, + "plugin_rejected": { + "type": "integer" + }, + "status_failed": { + "type": "integer" + }, + "status_incomplete": { + "type": "integer" + } + } + }, + "config_default_response": { + "type": "object", + "properties": { + "status": { + "type": "integer", + "description": "The HTTP status code of the response." + }, + "message": { + "type": "string", + "description": "A descriptive message about the response or the action taken." + }, + "data": { + "type": "object", + "description": "The data payload of the response, contents vary depending on the specific request and action.", + "additionalProperties": true + } + } } } } -} +}
\ No newline at end of file diff --git a/web/api/netdata-swagger.yaml b/web/api/netdata-swagger.yaml index 7fa852f4a3..5107bbe673 100644 --- a/web/api/netdata-swagger.yaml +++ b/web/api/netdata-swagger.yaml @@ -226,6 +226,129 @@ paths: description: No context id was supplied in the request. "404": description: No context with the given id is found. + /api/v1/config: + get: + operationId: getConfig + tags: + - dyncfg + description: | + Get dynamic configuration information. + parameters: + - name: action + in: query + description: The type of information required + schema: + type: string + enum: + - tree + - schema + - get + - enable + - disable + - restart + default: tree + - name: id + in: query + description: The ID of the dynamic configuration entity + schema: + type: string + - name: path + in: query + description: Top level path of the configuration entities, used with action 'tree' + schema: + type: string + default: '/' + - name: timeout + in: query + description: The timeout in seconds + schema: + type: number + default: 120 + responses: + "200": + description: The call was successful. + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/config_default_response' + - $ref: '#/components/schemas/config_tree' + - $ref: "#/components/schemas/config_schema" + "400": + description: Something is wrong with the request. + content: + application/json: + schema: + $ref: '#/components/schemas/config_default_response' + "404": + description: The configurable entity requests is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/config_default_response' + post: + operationId: postConfig + tags: + - dyncfg + description: | + Post dynamic configuration to Netdata. + parameters: + - name: action + in: query + description: The type of action required. + schema: + type: string + enum: + - add + - test + - update + - name: id + in: query + description: The ID of the dynamic configuration entity to configure. + schema: + type: string + - name: name + in: query + description: Name of the dynamic configuration entity, used with action 'add' + schema: + type: string + - name: timeout + in: query + description: The timeout in seconds + schema: + type: number + default: 120 + responses: + "200": + description: The call was successful. This also means the configuration is currently running. + content: + application/json: + schema: + $ref: '#/components/schemas/config_default_response' + "202": + description: The call was successful. The configuration has been accepted, but its status is not yet known. + content: + application/json: + schema: + $ref: '#/components/schemas/config_default_response' + "299": + description: The call was successful. The configuration has been accepted, but a restart is required to apply it. + content: + application/json: + schema: + $ref: '#/components/schemas/config_default_response' + "400": + description: Something is wrong with the request. + content: + application/json: + schema: + $ref: '#/components/schemas/config_default_response' + "404": + description: The configurable entity requests is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/config_default_response' /api/v2/data: get: operationId: dataQuery2 @@ -3259,3 +3382,105 @@ components: $ref: '#/components/schemas/weighted_dimension' weighted_dimension: type: number + config_schema: + type: object + properties: + jsonSchema: + type: object + description: Standard JSON Schema object describing the schema of each configurable entity. + uiSchema: + type: object + description: Schema for react-json-schema-form to drive the UI. Provides additional UI-specific configuration. + config_tree: + type: object + properties: + version: + type: integer + description: The version of dynamic configuration supported by the Netdata agent. + tree: + type: object + description: A map of configuration entity paths, each containing one or more configurable entities. + additionalProperties: + type: object + additionalProperties: + $ref: '#/components/schemas/config_entity' + attention: + $ref: '#/components/schemas/config_attention' + config_entity: + type: object + properties: + type: + type: string + description: Can be 'single' for entities appearing once, 'template' for entities supporting multiple instances, or 'job' for jobs belonging to a template. + status: + type: string + description: The current status of the entity. Values include 'accepted', 'running', 'failed', 'disabled', 'incomplete', or 'orphan'. + cmds: + type: array + items: + type: string + description: An array of the possible actions supported by this entity. + source_type: + type: string + description: The source type of the configuration (e.g., 'internal', 'stock', 'user', 'discovered', 'dyncfg'). + source: + type: string + description: Additional information about the source, formatted as comma-separated name-value pairs. + sync: + type: boolean + description: Indicates if this is an internal module (true) or an external plugin (false). + user_disabled: + type: boolean + description: True if the entity is disabled by the user. + restart_required: + type: boolean + description: True if the entity requires a restart after addition or update. + plugin_rejected: + type: boolean + description: True if a previously saved configuration failed to apply after a restart. + payload: + type: object + description: Object containing at least an 'available' boolean indicating if there's a saved configuration for this entity. + properties: + available: + type: boolean + saves: + type: integer + description: The number of times this configuration has been saved to disk by the dynamic configuration manager. + created_ut: + type: integer + format: int64 + description: The timestamp in microseconds when this dynamic configuration was first created. + modified_ut: + type: integer + format: int64 + description: The timestamp in microseconds when this dynamic configuration was last modified. + template: + type: string + description: Shows the template the job belongs to, applicable when type is 'job'. + config_attention: + type: object + properties: + degraded: + type: boolean + restart_required: + type: integer + plugin_rejected: + type: integer + status_failed: + type: integer + status_incomplete: + type: integer + config_default_response: + type: object + properties: + status: + type: integer + description: The HTTP status code of the response. + message: + type: string + description: A descriptive message about the response or the action taken. + data: + type: object + description: The data payload of the response, contents vary depending on the specific request and action. + additionalProperties: true diff --git a/web/api/web_api_v1.c b/web/api/web_api_v1.c index 59c04df10e..5033002d74 100644 --- a/web/api/web_api_v1.c +++ b/web/api/web_api_v1.c @@ -1548,8 +1548,7 @@ static int web_client_api_request_v1_config(RRDHOST *host, struct web_client *w, NULL, NULL, web_client_progress_functions_update, w, web_client_interrupt_callback, w, - w->payload, - buffer_tostring(source)); + w->payload, buffer_tostring(source)); return code; } |