diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index db0bdfdf15..c459277c7d 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -30853,6 +30853,94 @@ components: example: Jane Doe type: string type: object + DashboardWidgetValidationLayoutType: + description: Layout type used to apply dashboard-specific widget layout validation. + enum: + - ordered + - free + example: ordered + type: string + x-enum-varnames: + - ORDERED + - FREE + DashboardWidgetValidationReflowType: + description: Reflow behavior used for an ordered dashboard. + enum: + - auto + - fixed + example: auto + type: string + x-enum-varnames: + - AUTO + - FIXED + DashboardWidgetValidationRequest: + description: Request containing dashboard widgets and their layout context. + properties: + layout_type: + $ref: "#/components/schemas/DashboardWidgetValidationLayoutType" + reflow_type: + $ref: "#/components/schemas/DashboardWidgetValidationReflowType" + nullable: true + widgets: + description: Dashboard widgets to validate. + example: + - definition: + content: Valid note + type: note + items: + $ref: "#/components/schemas/DashboardWidgetValidationWidget" + type: array + required: + - widgets + - layout_type + type: object + DashboardWidgetValidationResponse: + description: Ordered validation results corresponding to the requested widgets. + properties: + results: + description: Validation results in the same order as the requested widgets. + items: + $ref: "#/components/schemas/DashboardWidgetValidationResult" + type: array + required: + - results + type: object + DashboardWidgetValidationResult: + description: Validation result for one dashboard widget. + properties: + error_message: + description: Validation error message, when the widget is invalid. + example: Invalid widget definition at position `0` of type `timeseries`. + nullable: true + type: string + error_path: + description: Path to the invalid value, when available. + example: "['requests', 0, 'display_type']" + nullable: true + type: string + is_valid: + description: Whether the widget passed validation. + example: false + type: boolean + widget_type: + description: Type of the validated widget, when available. + example: timeseries + nullable: true + type: string + required: + - is_valid + - widget_type + - error_message + - error_path + type: object + DashboardWidgetValidationWidget: + additionalProperties: {} + description: A dashboard widget to validate. + example: + definition: + content: Valid note + type: note + type: object DataAttributesRulesItemsIfTagExists: description: The behavior when the tag already exists. enum: @@ -138616,6 +138704,78 @@ paths: tags: - Dashboard Lists x-codegen-request-body-name: body + /api/v2/dashboard/widgets/validate: + post: + description: Validate dashboard widgets without creating or updating a dashboard. + operationId: ValidateDashboardWidgets + requestBody: + content: + application/json: + examples: + default: + value: + layout_type: ordered + widgets: + - definition: + content: Valid note + type: note + schema: + $ref: "#/components/schemas/DashboardWidgetValidationRequest" + required: true + responses: + "200": + content: + application/json: + examples: + default: + value: + results: + - error_message: + error_path: + is_valid: true + widget_type: note + schema: + $ref: "#/components/schemas/DashboardWidgetValidationResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Bad Request + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Forbidden + "422": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Unprocessable Entity + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - dashboards_read + - AuthZ: + - dashboards_write + summary: Validate dashboard widgets + tags: + - Dashboards + x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - dashboards_read + - dashboards_write + x-unstable: |- + **Note**: This endpoint is in Preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). /api/v2/dashboard/{dashboard_id}/shared: get: description: Retrieve shared dashboards associated with the specified dashboard. diff --git a/docs/datadog_api_client.v2.model.rst b/docs/datadog_api_client.v2.model.rst index c2a5e5aa47..0541bcdf8e 100644 --- a/docs/datadog_api_client.v2.model.rst +++ b/docs/datadog_api_client.v2.model.rst @@ -11743,6 +11743,48 @@ datadog\_api\_client.v2.model.dashboard\_usage\_user module :members: :show-inheritance: +datadog\_api\_client.v2.model.dashboard\_widget\_validation\_layout\_type module +-------------------------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.dashboard_widget_validation_layout_type + :members: + :show-inheritance: + +datadog\_api\_client.v2.model.dashboard\_widget\_validation\_reflow\_type module +-------------------------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.dashboard_widget_validation_reflow_type + :members: + :show-inheritance: + +datadog\_api\_client.v2.model.dashboard\_widget\_validation\_request module +--------------------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.dashboard_widget_validation_request + :members: + :show-inheritance: + +datadog\_api\_client.v2.model.dashboard\_widget\_validation\_response module +---------------------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.dashboard_widget_validation_response + :members: + :show-inheritance: + +datadog\_api\_client.v2.model.dashboard\_widget\_validation\_result module +-------------------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.dashboard_widget_validation_result + :members: + :show-inheritance: + +datadog\_api\_client.v2.model.dashboard\_widget\_validation\_widget module +-------------------------------------------------------------------------- + +.. automodule:: datadog_api_client.v2.model.dashboard_widget_validation_widget + :members: + :show-inheritance: + datadog\_api\_client.v2.model.data\_attributes\_rules\_items\_if\_tag\_exists module ------------------------------------------------------------------------------------ diff --git a/examples/v2/dashboards/ValidateDashboardWidgets.py b/examples/v2/dashboards/ValidateDashboardWidgets.py new file mode 100644 index 0000000000..e1294d93ec --- /dev/null +++ b/examples/v2/dashboards/ValidateDashboardWidgets.py @@ -0,0 +1,26 @@ +""" +Validate dashboard widgets returns "OK" response +""" + +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.dashboards_api import DashboardsApi +from datadog_api_client.v2.model.dashboard_widget_validation_layout_type import DashboardWidgetValidationLayoutType +from datadog_api_client.v2.model.dashboard_widget_validation_reflow_type import DashboardWidgetValidationReflowType +from datadog_api_client.v2.model.dashboard_widget_validation_request import DashboardWidgetValidationRequest +from datadog_api_client.v2.model.dashboard_widget_validation_widget import DashboardWidgetValidationWidget + +body = DashboardWidgetValidationRequest( + layout_type=DashboardWidgetValidationLayoutType.ORDERED, + reflow_type=DashboardWidgetValidationReflowType.AUTO, + widgets=[ + DashboardWidgetValidationWidget([("definition", "{'content': 'Valid note', 'type': 'note'}")]), + ], +) + +configuration = Configuration() +configuration.unstable_operations["validate_dashboard_widgets"] = True +with ApiClient(configuration) as api_client: + api_instance = DashboardsApi(api_client) + response = api_instance.validate_dashboard_widgets(body=body) + + print(response) diff --git a/src/datadog_api_client/configuration.py b/src/datadog_api_client/configuration.py index 9c01331488..e21fdcdde9 100644 --- a/src/datadog_api_client/configuration.py +++ b/src/datadog_api_client/configuration.py @@ -466,13 +466,14 @@ def __init__( "v2.list_csm_agentless_hosts": False, "v2.list_csm_unified_host_facets": False, "v2.list_csm_unified_hosts": False, + "v2.get_dashboard_usage": False, + "v2.list_dashboards_usage": False, + "v2.validate_dashboard_widgets": False, "v2.list_shared_dashboards_by_dashboard_id": False, "v2.create_dashboard_secure_embed": False, "v2.delete_dashboard_secure_embed": False, "v2.get_dashboard_secure_embed": False, "v2.update_dashboard_secure_embed": False, - "v2.get_dashboard_usage": False, - "v2.list_dashboards_usage": False, "v2.get_data_observability_monitor_run_status": False, "v2.run_data_observability_monitor": False, "v2.create_dataset": False, diff --git a/src/datadog_api_client/v2/api/dashboards_api.py b/src/datadog_api_client/v2/api/dashboards_api.py index efe51c6dc8..ffcffbe7e2 100644 --- a/src/datadog_api_client/v2/api/dashboards_api.py +++ b/src/datadog_api_client/v2/api/dashboards_api.py @@ -14,6 +14,8 @@ UnsetType, unset, ) +from datadog_api_client.v2.model.dashboard_widget_validation_response import DashboardWidgetValidationResponse +from datadog_api_client.v2.model.dashboard_widget_validation_request import DashboardWidgetValidationRequest from datadog_api_client.v2.model.list_dashboards_usage_response import ListDashboardsUsageResponse from datadog_api_client.v2.model.dashboard_usage import DashboardUsage from datadog_api_client.v2.model.dashboard_usage_response import DashboardUsageResponse @@ -95,6 +97,26 @@ def __init__(self, api_client=None): api_client=api_client, ) + self._validate_dashboard_widgets_endpoint = _Endpoint( + settings={ + "response_type": (DashboardWidgetValidationResponse,), + "auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"], + "endpoint_path": "/api/v2/dashboard/widgets/validate", + "operation_id": "validate_dashboard_widgets", + "http_method": "POST", + "version": "v2", + }, + params_map={ + "body": { + "required": True, + "openapi_types": (DashboardWidgetValidationRequest,), + "location": "body", + }, + }, + headers_map={"accept": ["application/json"], "content_type": ["application/json"]}, + api_client=api_client, + ) + def get_dashboard_usage( self, dashboard_id: str, @@ -197,3 +219,19 @@ def list_dashboards_usage_with_pagination( "kwargs": kwargs, } return endpoint.call_with_http_info_paginated(pagination) + + def validate_dashboard_widgets( + self, + body: DashboardWidgetValidationRequest, + ) -> DashboardWidgetValidationResponse: + """Validate dashboard widgets. + + Validate dashboard widgets without creating or updating a dashboard. + + :type body: DashboardWidgetValidationRequest + :rtype: DashboardWidgetValidationResponse + """ + kwargs: Dict[str, Any] = {} + kwargs["body"] = body + + return self._validate_dashboard_widgets_endpoint.call_with_http_info(**kwargs) diff --git a/src/datadog_api_client/v2/model/dashboard_widget_validation_layout_type.py b/src/datadog_api_client/v2/model/dashboard_widget_validation_layout_type.py new file mode 100644 index 0000000000..5c42a0791b --- /dev/null +++ b/src/datadog_api_client/v2/model/dashboard_widget_validation_layout_type.py @@ -0,0 +1,38 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + + +from datadog_api_client.model_utils import ( + ModelSimple, + cached_property, +) + +from typing import ClassVar + + +class DashboardWidgetValidationLayoutType(ModelSimple): + """ + Layout type used to apply dashboard-specific widget layout validation. + + :param value: Must be one of ["ordered", "free"]. + :type value: str + """ + + allowed_values = { + "ordered", + "free", + } + ORDERED: ClassVar["DashboardWidgetValidationLayoutType"] + FREE: ClassVar["DashboardWidgetValidationLayoutType"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +DashboardWidgetValidationLayoutType.ORDERED = DashboardWidgetValidationLayoutType("ordered") +DashboardWidgetValidationLayoutType.FREE = DashboardWidgetValidationLayoutType("free") diff --git a/src/datadog_api_client/v2/model/dashboard_widget_validation_reflow_type.py b/src/datadog_api_client/v2/model/dashboard_widget_validation_reflow_type.py new file mode 100644 index 0000000000..046090a721 --- /dev/null +++ b/src/datadog_api_client/v2/model/dashboard_widget_validation_reflow_type.py @@ -0,0 +1,38 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + + +from datadog_api_client.model_utils import ( + ModelSimple, + cached_property, +) + +from typing import ClassVar + + +class DashboardWidgetValidationReflowType(ModelSimple): + """ + Reflow behavior used for an ordered dashboard. + + :param value: Must be one of ["auto", "fixed"]. + :type value: str + """ + + allowed_values = { + "auto", + "fixed", + } + AUTO: ClassVar["DashboardWidgetValidationReflowType"] + FIXED: ClassVar["DashboardWidgetValidationReflowType"] + + @cached_property + def openapi_types(_): + return { + "value": (str,), + } + + +DashboardWidgetValidationReflowType.AUTO = DashboardWidgetValidationReflowType("auto") +DashboardWidgetValidationReflowType.FIXED = DashboardWidgetValidationReflowType("fixed") diff --git a/src/datadog_api_client/v2/model/dashboard_widget_validation_request.py b/src/datadog_api_client/v2/model/dashboard_widget_validation_request.py new file mode 100644 index 0000000000..9cbb735cab --- /dev/null +++ b/src/datadog_api_client/v2/model/dashboard_widget_validation_request.py @@ -0,0 +1,69 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import List, Union, TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + unset, + UnsetType, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.dashboard_widget_validation_layout_type import DashboardWidgetValidationLayoutType + from datadog_api_client.v2.model.dashboard_widget_validation_reflow_type import DashboardWidgetValidationReflowType + from datadog_api_client.v2.model.dashboard_widget_validation_widget import DashboardWidgetValidationWidget + + +class DashboardWidgetValidationRequest(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.dashboard_widget_validation_layout_type import ( + DashboardWidgetValidationLayoutType, + ) + from datadog_api_client.v2.model.dashboard_widget_validation_reflow_type import ( + DashboardWidgetValidationReflowType, + ) + from datadog_api_client.v2.model.dashboard_widget_validation_widget import DashboardWidgetValidationWidget + + return { + "layout_type": (DashboardWidgetValidationLayoutType,), + "reflow_type": (DashboardWidgetValidationReflowType,), + "widgets": ([DashboardWidgetValidationWidget],), + } + + attribute_map = { + "layout_type": "layout_type", + "reflow_type": "reflow_type", + "widgets": "widgets", + } + + def __init__( + self_, + layout_type: DashboardWidgetValidationLayoutType, + widgets: List[DashboardWidgetValidationWidget], + reflow_type: Union[DashboardWidgetValidationReflowType, UnsetType] = unset, + **kwargs, + ): + """ + Request containing dashboard widgets and their layout context. + + :param layout_type: Layout type used to apply dashboard-specific widget layout validation. + :type layout_type: DashboardWidgetValidationLayoutType + + :param reflow_type: Reflow behavior used for an ordered dashboard. + :type reflow_type: DashboardWidgetValidationReflowType, optional + + :param widgets: Dashboard widgets to validate. + :type widgets: [DashboardWidgetValidationWidget] + """ + if reflow_type is not unset: + kwargs["reflow_type"] = reflow_type + super().__init__(kwargs) + + self_.layout_type = layout_type + self_.widgets = widgets diff --git a/src/datadog_api_client/v2/model/dashboard_widget_validation_response.py b/src/datadog_api_client/v2/model/dashboard_widget_validation_response.py new file mode 100644 index 0000000000..f7290d5797 --- /dev/null +++ b/src/datadog_api_client/v2/model/dashboard_widget_validation_response.py @@ -0,0 +1,40 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import List, TYPE_CHECKING + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, +) + + +if TYPE_CHECKING: + from datadog_api_client.v2.model.dashboard_widget_validation_result import DashboardWidgetValidationResult + + +class DashboardWidgetValidationResponse(ModelNormal): + @cached_property + def openapi_types(_): + from datadog_api_client.v2.model.dashboard_widget_validation_result import DashboardWidgetValidationResult + + return { + "results": ([DashboardWidgetValidationResult],), + } + + attribute_map = { + "results": "results", + } + + def __init__(self_, results: List[DashboardWidgetValidationResult], **kwargs): + """ + Ordered validation results corresponding to the requested widgets. + + :param results: Validation results in the same order as the requested widgets. + :type results: [DashboardWidgetValidationResult] + """ + super().__init__(kwargs) + + self_.results = results diff --git a/src/datadog_api_client/v2/model/dashboard_widget_validation_result.py b/src/datadog_api_client/v2/model/dashboard_widget_validation_result.py new file mode 100644 index 0000000000..0e0dc596f4 --- /dev/null +++ b/src/datadog_api_client/v2/model/dashboard_widget_validation_result.py @@ -0,0 +1,60 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + +from typing import Union + +from datadog_api_client.model_utils import ( + ModelNormal, + cached_property, + none_type, +) + + +class DashboardWidgetValidationResult(ModelNormal): + @cached_property + def openapi_types(_): + return { + "error_message": (str, none_type), + "error_path": (str, none_type), + "is_valid": (bool,), + "widget_type": (str, none_type), + } + + attribute_map = { + "error_message": "error_message", + "error_path": "error_path", + "is_valid": "is_valid", + "widget_type": "widget_type", + } + + def __init__( + self_, + error_message: Union[str, none_type], + error_path: Union[str, none_type], + is_valid: bool, + widget_type: Union[str, none_type], + **kwargs, + ): + """ + Validation result for one dashboard widget. + + :param error_message: Validation error message, when the widget is invalid. + :type error_message: str, none_type + + :param error_path: Path to the invalid value, when available. + :type error_path: str, none_type + + :param is_valid: Whether the widget passed validation. + :type is_valid: bool + + :param widget_type: Type of the validated widget, when available. + :type widget_type: str, none_type + """ + super().__init__(kwargs) + + self_.error_message = error_message + self_.error_path = error_path + self_.is_valid = is_valid + self_.widget_type = widget_type diff --git a/src/datadog_api_client/v2/model/dashboard_widget_validation_widget.py b/src/datadog_api_client/v2/model/dashboard_widget_validation_widget.py new file mode 100644 index 0000000000..79e1368c6b --- /dev/null +++ b/src/datadog_api_client/v2/model/dashboard_widget_validation_widget.py @@ -0,0 +1,17 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2019-Present Datadog, Inc. +from __future__ import annotations + + +from datadog_api_client.model_utils import ( + ModelNormal, +) + + +class DashboardWidgetValidationWidget(ModelNormal): + def __init__(self_, **kwargs): + """ + A dashboard widget to validate. + """ + super().__init__(kwargs) diff --git a/src/datadog_api_client/v2/models/__init__.py b/src/datadog_api_client/v2/models/__init__.py index 7200f76674..6ebeef12d4 100644 --- a/src/datadog_api_client/v2/models/__init__.py +++ b/src/datadog_api_client/v2/models/__init__.py @@ -2311,6 +2311,12 @@ from datadog_api_client.v2.model.dashboard_usage_response import DashboardUsageResponse from datadog_api_client.v2.model.dashboard_usage_type import DashboardUsageType from datadog_api_client.v2.model.dashboard_usage_user import DashboardUsageUser +from datadog_api_client.v2.model.dashboard_widget_validation_layout_type import DashboardWidgetValidationLayoutType +from datadog_api_client.v2.model.dashboard_widget_validation_reflow_type import DashboardWidgetValidationReflowType +from datadog_api_client.v2.model.dashboard_widget_validation_request import DashboardWidgetValidationRequest +from datadog_api_client.v2.model.dashboard_widget_validation_response import DashboardWidgetValidationResponse +from datadog_api_client.v2.model.dashboard_widget_validation_result import DashboardWidgetValidationResult +from datadog_api_client.v2.model.dashboard_widget_validation_widget import DashboardWidgetValidationWidget from datadog_api_client.v2.model.data_attributes_rules_items_if_tag_exists import DataAttributesRulesItemsIfTagExists from datadog_api_client.v2.model.data_attributes_rules_items_mapping import DataAttributesRulesItemsMapping from datadog_api_client.v2.model.data_deletion_response_item import DataDeletionResponseItem @@ -12313,6 +12319,12 @@ "DashboardUsageResponse", "DashboardUsageType", "DashboardUsageUser", + "DashboardWidgetValidationLayoutType", + "DashboardWidgetValidationReflowType", + "DashboardWidgetValidationRequest", + "DashboardWidgetValidationResponse", + "DashboardWidgetValidationResult", + "DashboardWidgetValidationWidget", "DataAttributesRulesItemsIfTagExists", "DataAttributesRulesItemsMapping", "DataDeletionResponseItem", diff --git a/tests/v2/features/dashboards.feature b/tests/v2/features/dashboards.feature index 347955175e..ce7cef9a96 100644 --- a/tests/v2/features/dashboards.feature +++ b/tests/v2/features/dashboards.feature @@ -99,3 +99,32 @@ Feature: Dashboards When the request is sent Then the response status is 200 OK And the response "meta.page" has field "total" + + @generated @skip @team:DataDog/dashboards-backend + Scenario: Validate dashboard widgets returns "Bad Request" response + Given operation "ValidateDashboardWidgets" enabled + And new "ValidateDashboardWidgets" request + And body with value {"layout_type": "ordered", "reflow_type": "auto", "widgets": [{"definition": {"content": "Valid note", "type": "note"}}]} + When the request is sent + Then the response status is 400 Bad Request + + @team:DataDog/dashboards-backend + Scenario: Validate dashboard widgets returns "OK" response + Given operation "ValidateDashboardWidgets" enabled + And new "ValidateDashboardWidgets" request + And body with value {"layout_type": "ordered", "reflow_type": "auto", "widgets": [{"definition": {"content": "Valid note", "type": "note"}}]} + When the request is sent + Then the response status is 200 OK + And the response "results" has length 1 + And the response "results[0].is_valid" is equal to true + And the response "results[0].widget_type" is equal to "note" + And the response "results[0]" has field "error_message" + And the response "results[0]" has field "error_path" + + @generated @skip @team:DataDog/dashboards-backend + Scenario: Validate dashboard widgets returns "Unprocessable Entity" response + Given operation "ValidateDashboardWidgets" enabled + And new "ValidateDashboardWidgets" request + And body with value {"layout_type": "ordered", "reflow_type": "auto", "widgets": [{"definition": {"content": "Valid note", "type": "note"}}]} + When the request is sent + Then the response status is 422 Unprocessable Entity diff --git a/tests/v2/features/undo.json b/tests/v2/features/undo.json index df961ee10c..5d00d889c2 100644 --- a/tests/v2/features/undo.json +++ b/tests/v2/features/undo.json @@ -2157,6 +2157,12 @@ "type": "safe" } }, + "ValidateDashboardWidgets": { + "tag": "Dashboards", + "undo": { + "type": "safe" + } + }, "ListSharedDashboardsByDashboardId": { "tag": "Dashboard Sharing", "undo": {