diff --git a/.generated-info b/.generated-info index ca23f6db0fc2..62c358b61e38 100644 --- a/.generated-info +++ b/.generated-info @@ -1,4 +1,4 @@ { - "spec_repo_commit": "8001cbb", - "generated": "2025-08-13 20:27:09.207" + "spec_repo_commit": "c9f30db", + "generated": "2025-08-15 16:35:22.218" } diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 5ab5923ba83d..795350a5934f 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -14454,6 +14454,10 @@ components: description: Entity definition in raw JSON or YAML representation. example: "apiVersion: v3\nkind: service\nmetadata:\n name: myservice\n" type: string + EntityReference: + description: The unique reference for an IDP entity. + example: service:my-service + type: string EntityRelationships: description: Entity relationships. properties: @@ -43591,6 +43595,57 @@ components: id: $ref: '#/components/schemas/ApiID' type: object + UpdateOutcomesAsyncAttributes: + description: The JSON:API attributes for a batched set of scorecard outcomes. + properties: + results: + description: Set of scorecard outcomes to update asynchronously. + items: + $ref: '#/components/schemas/UpdateOutcomesAsyncRequestItem' + type: array + type: object + UpdateOutcomesAsyncRequest: + description: Scorecard outcomes batch request. + properties: + data: + $ref: '#/components/schemas/UpdateOutcomesAsyncRequestData' + type: object + UpdateOutcomesAsyncRequestData: + description: Scorecard outcomes batch request data. + properties: + attributes: + $ref: '#/components/schemas/UpdateOutcomesAsyncAttributes' + type: + $ref: '#/components/schemas/UpdateOutcomesAsyncType' + type: object + UpdateOutcomesAsyncRequestItem: + description: Scorecard outcome for a single entity and rule. + properties: + entity_reference: + $ref: '#/components/schemas/EntityReference' + remarks: + description: Any remarks regarding the scorecard rule's evaluation, and + supports HTML hyperlinks. + example: 'See: Services' + type: string + rule_id: + $ref: '#/components/schemas/RuleId' + state: + $ref: '#/components/schemas/State' + required: + - rule_id + - entity_reference + - state + type: object + UpdateOutcomesAsyncType: + default: batched-outcome + description: The JSON:API type for scorecard outcomes. + enum: + - batched-outcome + example: batched-outcome + type: string + x-enum-varnames: + - BATCHED_OUTCOME UpdateResourceEvaluationFiltersRequest: description: Request object to update a resource filter. properties: @@ -61575,6 +61630,37 @@ paths: resultsPath: data x-unstable: '**Note**: This endpoint is in public beta. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).' + post: + description: Updates multiple scorecard rule outcomes in a single batched request. + operationId: UpdateScorecardOutcomesAsync + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateOutcomesAsyncRequest' + description: Set of scorecard outcomes. + required: true + responses: + '202': + description: Accepted + '400': + $ref: '#/components/responses/BadRequestResponse' + '403': + $ref: '#/components/responses/ForbiddenResponse' + '429': + $ref: '#/components/responses/TooManyRequestsResponse' + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - apm_service_catalog_write + summary: Update Scorecard outcomes asynchronously + tags: + - Service Scorecards + x-codegen-request-body-name: body + x-unstable: '**Note**: This endpoint is in public beta. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/).' /api/v2/scorecard/outcomes/batch: post: diff --git a/features/v2/service_scorecards.feature b/features/v2/service_scorecards.feature index 11d2c7f43287..8ecf48ff1d21 100644 --- a/features/v2/service_scorecards.feature +++ b/features/v2/service_scorecards.feature @@ -121,6 +121,22 @@ Feature: Service Scorecards Then the response status is 200 OK And the response has 4 items + @generated @skip @team:DataDog/service-catalog + Scenario: Update Scorecard outcomes asynchronously returns "Accepted" response + Given operation "UpdateScorecardOutcomesAsync" enabled + And new "UpdateScorecardOutcomesAsync" request + And body with value {"data": {"attributes": {"results": [{"entity_reference": "service:my-service", "remarks": "See: Services", "rule_id": "q8MQxk8TCqrHnWkx", "state": "pass"}]}, "type": "batched-outcome"}} + When the request is sent + Then the response status is 202 Accepted + + @generated @skip @team:DataDog/service-catalog + Scenario: Update Scorecard outcomes asynchronously returns "Bad Request" response + Given operation "UpdateScorecardOutcomesAsync" enabled + And new "UpdateScorecardOutcomesAsync" request + And body with value {"data": {"attributes": {"results": [{"entity_reference": "service:my-service", "remarks": "See: Services", "rule_id": "q8MQxk8TCqrHnWkx", "state": "pass"}]}, "type": "batched-outcome"}} + When the request is sent + Then the response status is 400 Bad Request + @generated @skip @team:DataDog/service-catalog Scenario: Update an existing rule returns "Bad Request" response Given operation "UpdateScorecardRule" enabled diff --git a/features/v2/undo.json b/features/v2/undo.json index fd14fad09365..54c7d933a1db 100644 --- a/features/v2/undo.json +++ b/features/v2/undo.json @@ -2742,6 +2742,12 @@ "type": "safe" } }, + "UpdateScorecardOutcomesAsync": { + "tag": "Service Scorecards", + "undo": { + "type": "idempotent" + } + }, "CreateScorecardOutcomesBatch": { "tag": "Service Scorecards", "undo": { diff --git a/private/bdd_runner/src/support/scenarios_model_mapping.ts b/private/bdd_runner/src/support/scenarios_model_mapping.ts index 0779d7fa60c6..e102c8a671af 100644 --- a/private/bdd_runner/src/support/scenarios_model_mapping.ts +++ b/private/bdd_runner/src/support/scenarios_model_mapping.ts @@ -7112,6 +7112,13 @@ export const ScenariosModelMappings: { [key: string]: OperationMapping } = { }, operationResponseType: "OutcomesResponse", }, + "ServiceScorecardsApi.V2.UpdateScorecardOutcomesAsync": { + body: { + type: "UpdateOutcomesAsyncRequest", + format: "", + }, + operationResponseType: "{}", + }, "ServiceScorecardsApi.V2.CreateScorecardOutcomesBatch": { body: { type: "OutcomesBatchRequest", diff --git a/services/service_scorecards/src/v2/ServiceScorecardsApi.ts b/services/service_scorecards/src/v2/ServiceScorecardsApi.ts index a608d0ad017f..a08c72f952ac 100644 --- a/services/service_scorecards/src/v2/ServiceScorecardsApi.ts +++ b/services/service_scorecards/src/v2/ServiceScorecardsApi.ts @@ -31,6 +31,7 @@ import { OutcomesBatchRequest } from "./models/OutcomesBatchRequest"; import { OutcomesBatchResponse } from "./models/OutcomesBatchResponse"; import { OutcomesResponse } from "./models/OutcomesResponse"; import { OutcomesResponseDataItem } from "./models/OutcomesResponseDataItem"; +import { UpdateOutcomesAsyncRequest } from "./models/UpdateOutcomesAsyncRequest"; import { UpdateRuleRequest } from "./models/UpdateRuleRequest"; import { UpdateRuleResponse } from "./models/UpdateRuleResponse"; import { version } from "../version"; @@ -471,6 +472,67 @@ export class ServiceScorecardsApiRequestFactory extends BaseAPIRequestFactory { return requestContext; } + public async updateScorecardOutcomesAsync( + body: UpdateOutcomesAsyncRequest, + _options?: Configuration, + ): Promise { + const _config = _options || this.configuration; + + if ( + !_config.unstableOperations[ + "ServiceScorecardsApi.v2.updateScorecardOutcomesAsync" + ] + ) { + throw new Error( + "Unstable operation 'updateScorecardOutcomesAsync' is disabled. Enable it by setting `configuration.unstableOperations['ServiceScorecardsApi.v2.updateScorecardOutcomesAsync'] = true`", + ); + } + + // verify required parameter 'body' is not null or undefined + if (body === null || body === undefined) { + throw new RequiredError("body", "updateScorecardOutcomesAsync"); + } + + // Path Params + const localVarPath = "/api/v2/scorecard/outcomes"; + + // Make Request Context + const { server, overrides } = _config.getServerAndOverrides( + "ServiceScorecardsApi.v2.updateScorecardOutcomesAsync", + ServiceScorecardsApi.operationServers, + ); + const requestContext = server.makeRequestContext( + localVarPath, + HttpMethod.POST, + overrides, + ); + requestContext.setHeaderParam("Accept", "*/*"); + requestContext.setHttpConfig(_config.httpConfig); + + // Set User-Agent + if (this.userAgent) { + requestContext.setHeaderParam("User-Agent", this.userAgent); + } + + // Body Params + const contentType = getPreferredMediaType(["application/json"]); + requestContext.setHeaderParam("Content-Type", contentType); + const serializedBody = stringify( + serialize(body, TypingInfo, "UpdateOutcomesAsyncRequest", ""), + contentType, + ); + requestContext.setBody(serializedBody); + + // Apply auth methods + applySecurityAuthentication(_config, requestContext, [ + "apiKeyAuth", + "appKeyAuth", + "AuthZ", + ]); + + return requestContext; + } + public async updateScorecardRule( ruleId: string, body: UpdateRuleRequest, @@ -829,6 +891,55 @@ export class ServiceScorecardsApiResponseProcessor { ); } + /** + * Unwraps the actual response sent by the server from the response context and deserializes the response content + * to the expected objects + * + * @params response Response returned by the server for a request to updateScorecardOutcomesAsync + * @throws ApiException if the response code was not in [200, 299] + */ + public async updateScorecardOutcomesAsync( + response: ResponseContext, + ): Promise { + const contentType = normalizeMediaType(response.headers["content-type"]); + if (response.httpStatusCode === 202) { + return; + } + if ( + response.httpStatusCode === 400 || + response.httpStatusCode === 403 || + response.httpStatusCode === 429 + ) { + const bodyText = parse(await response.body.text(), contentType); + let body: APIErrorResponse; + try { + body = deserialize( + bodyText, + TypingInfo, + "APIErrorResponse", + ) as APIErrorResponse; + } catch (error) { + logger.debug(`Got error deserializing error: ${error}`); + throw new ApiException( + response.httpStatusCode, + bodyText, + ); + } + throw new ApiException(response.httpStatusCode, body); + } + + // Work around for missing responses in specification, e.g. for petstore.yaml + if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) { + return; + } + + const body = (await response.body.text()) || ""; + throw new ApiException( + response.httpStatusCode, + 'Unknown API Status Code!\nBody: "' + body + '"', + ); + } + /** * Unwraps the actual response sent by the server from the response context and deserializes the response content * to the expected objects @@ -1020,6 +1131,14 @@ export interface ServiceScorecardsApiListScorecardRulesRequest { fieldsScorecard?: string; } +export interface ServiceScorecardsApiUpdateScorecardOutcomesAsyncRequest { + /** + * Set of scorecard outcomes. + * @type UpdateOutcomesAsyncRequest + */ + body: UpdateOutcomesAsyncRequest; +} + export interface ServiceScorecardsApiUpdateScorecardRuleRequest { /** * The ID of the rule. @@ -1276,6 +1395,27 @@ export class ServiceScorecardsApi { } } + /** + * Updates multiple scorecard rule outcomes in a single batched request. + * @param param The request object + */ + public updateScorecardOutcomesAsync( + param: ServiceScorecardsApiUpdateScorecardOutcomesAsyncRequest, + options?: Configuration, + ): Promise { + const requestContextPromise = + this.requestFactory.updateScorecardOutcomesAsync(param.body, options); + return requestContextPromise.then((requestContext) => { + return this.configuration.httpApi + .send(requestContext) + .then((responseContext) => { + return this.responseProcessor.updateScorecardOutcomesAsync( + responseContext, + ); + }); + }); + } + /** * Updates an existing rule. * @param param The request object diff --git a/services/service_scorecards/src/v2/index.ts b/services/service_scorecards/src/v2/index.ts index 5938c9fd8250..b5ef03e9f8c6 100644 --- a/services/service_scorecards/src/v2/index.ts +++ b/services/service_scorecards/src/v2/index.ts @@ -4,6 +4,7 @@ export { ServiceScorecardsApiDeleteScorecardRuleRequest, ServiceScorecardsApiListScorecardOutcomesRequest, ServiceScorecardsApiListScorecardRulesRequest, + ServiceScorecardsApiUpdateScorecardOutcomesAsyncRequest, ServiceScorecardsApiUpdateScorecardRuleRequest, ServiceScorecardsApi, } from "./ServiceScorecardsApi"; @@ -40,6 +41,11 @@ export { RuleOutcomeRelationships } from "./models/RuleOutcomeRelationships"; export { RuleType } from "./models/RuleType"; export { ScorecardType } from "./models/ScorecardType"; export { State } from "./models/State"; +export { UpdateOutcomesAsyncAttributes } from "./models/UpdateOutcomesAsyncAttributes"; +export { UpdateOutcomesAsyncRequest } from "./models/UpdateOutcomesAsyncRequest"; +export { UpdateOutcomesAsyncRequestData } from "./models/UpdateOutcomesAsyncRequestData"; +export { UpdateOutcomesAsyncRequestItem } from "./models/UpdateOutcomesAsyncRequestItem"; +export { UpdateOutcomesAsyncType } from "./models/UpdateOutcomesAsyncType"; export { UpdateRuleRequest } from "./models/UpdateRuleRequest"; export { UpdateRuleRequestData } from "./models/UpdateRuleRequestData"; export { UpdateRuleResponse } from "./models/UpdateRuleResponse"; diff --git a/services/service_scorecards/src/v2/models/TypingInfo.ts b/services/service_scorecards/src/v2/models/TypingInfo.ts index 4d78f72c506b..35fd57717a50 100644 --- a/services/service_scorecards/src/v2/models/TypingInfo.ts +++ b/services/service_scorecards/src/v2/models/TypingInfo.ts @@ -27,6 +27,10 @@ import { RelationshipToRuleData } from "./RelationshipToRuleData"; import { RelationshipToRuleDataObject } from "./RelationshipToRuleDataObject"; import { RuleAttributes } from "./RuleAttributes"; import { RuleOutcomeRelationships } from "./RuleOutcomeRelationships"; +import { UpdateOutcomesAsyncAttributes } from "./UpdateOutcomesAsyncAttributes"; +import { UpdateOutcomesAsyncRequest } from "./UpdateOutcomesAsyncRequest"; +import { UpdateOutcomesAsyncRequestData } from "./UpdateOutcomesAsyncRequestData"; +import { UpdateOutcomesAsyncRequestItem } from "./UpdateOutcomesAsyncRequestItem"; import { UpdateRuleRequest } from "./UpdateRuleRequest"; import { UpdateRuleRequestData } from "./UpdateRuleRequestData"; import { UpdateRuleResponse } from "./UpdateRuleResponse"; @@ -39,6 +43,7 @@ export const TypingInfo: ModelTypingInfo = { RuleType: ["rule"], ScorecardType: ["scorecard"], State: ["pass", "fail", "skip"], + UpdateOutcomesAsyncType: ["batched-outcome"], }, oneOfMap: {}, typeMap: { @@ -70,6 +75,10 @@ export const TypingInfo: ModelTypingInfo = { RelationshipToRuleDataObject: RelationshipToRuleDataObject, RuleAttributes: RuleAttributes, RuleOutcomeRelationships: RuleOutcomeRelationships, + UpdateOutcomesAsyncAttributes: UpdateOutcomesAsyncAttributes, + UpdateOutcomesAsyncRequest: UpdateOutcomesAsyncRequest, + UpdateOutcomesAsyncRequestData: UpdateOutcomesAsyncRequestData, + UpdateOutcomesAsyncRequestItem: UpdateOutcomesAsyncRequestItem, UpdateRuleRequest: UpdateRuleRequest, UpdateRuleRequestData: UpdateRuleRequestData, UpdateRuleResponse: UpdateRuleResponse, diff --git a/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncAttributes.ts b/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncAttributes.ts new file mode 100644 index 000000000000..b69b39828635 --- /dev/null +++ b/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncAttributes.ts @@ -0,0 +1,46 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { UpdateOutcomesAsyncRequestItem } from "./UpdateOutcomesAsyncRequestItem"; + +/** + * The JSON:API attributes for a batched set of scorecard outcomes. + */ +export class UpdateOutcomesAsyncAttributes { + /** + * Set of scorecard outcomes to update asynchronously. + */ + "results"?: Array; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + results: { + baseName: "results", + type: "Array", + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return UpdateOutcomesAsyncAttributes.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncRequest.ts b/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncRequest.ts new file mode 100644 index 000000000000..da9801766827 --- /dev/null +++ b/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncRequest.ts @@ -0,0 +1,46 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { UpdateOutcomesAsyncRequestData } from "./UpdateOutcomesAsyncRequestData"; + +/** + * Scorecard outcomes batch request. + */ +export class UpdateOutcomesAsyncRequest { + /** + * Scorecard outcomes batch request data. + */ + "data"?: UpdateOutcomesAsyncRequestData; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + data: { + baseName: "data", + type: "UpdateOutcomesAsyncRequestData", + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return UpdateOutcomesAsyncRequest.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncRequestData.ts b/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncRequestData.ts new file mode 100644 index 000000000000..c05605b2d06e --- /dev/null +++ b/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncRequestData.ts @@ -0,0 +1,55 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { UpdateOutcomesAsyncAttributes } from "./UpdateOutcomesAsyncAttributes"; +import { UpdateOutcomesAsyncType } from "./UpdateOutcomesAsyncType"; + +/** + * Scorecard outcomes batch request data. + */ +export class UpdateOutcomesAsyncRequestData { + /** + * The JSON:API attributes for a batched set of scorecard outcomes. + */ + "attributes"?: UpdateOutcomesAsyncAttributes; + /** + * The JSON:API type for scorecard outcomes. + */ + "type"?: UpdateOutcomesAsyncType; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + attributes: { + baseName: "attributes", + type: "UpdateOutcomesAsyncAttributes", + }, + type: { + baseName: "type", + type: "UpdateOutcomesAsyncType", + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return UpdateOutcomesAsyncRequestData.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncRequestItem.ts b/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncRequestItem.ts new file mode 100644 index 000000000000..a34d7472a872 --- /dev/null +++ b/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncRequestItem.ts @@ -0,0 +1,73 @@ +import { AttributeTypeMap } from "@datadog/datadog-api-client"; + +import { State } from "./State"; + +/** + * Scorecard outcome for a single entity and rule. + */ +export class UpdateOutcomesAsyncRequestItem { + /** + * The unique reference for an IDP entity. + */ + "entityReference": string; + /** + * Any remarks regarding the scorecard rule's evaluation, and supports HTML hyperlinks. + */ + "remarks"?: string; + /** + * The unique ID for a scorecard rule. + */ + "ruleId": string; + /** + * The state of the rule evaluation. + */ + "state": State; + /** + * A container for additional, undeclared properties. + * This is a holder for any undeclared properties as specified with + * the 'additionalProperties' keyword in the OAS document. + */ + "additionalProperties"?: { [key: string]: any }; + /** + * @ignore + */ + "_unparsed"?: boolean; + + /** + * @ignore + */ + static readonly attributeTypeMap: AttributeTypeMap = { + entityReference: { + baseName: "entity_reference", + type: "string", + required: true, + }, + remarks: { + baseName: "remarks", + type: "string", + }, + ruleId: { + baseName: "rule_id", + type: "string", + required: true, + }, + state: { + baseName: "state", + type: "State", + required: true, + }, + additionalProperties: { + baseName: "additionalProperties", + type: "{ [key: string]: any; }", + }, + }; + + /** + * @ignore + */ + static getAttributeTypeMap(): AttributeTypeMap { + return UpdateOutcomesAsyncRequestItem.attributeTypeMap; + } + + public constructor() {} +} diff --git a/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncType.ts b/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncType.ts new file mode 100644 index 000000000000..45b55a91f0fe --- /dev/null +++ b/services/service_scorecards/src/v2/models/UpdateOutcomesAsyncType.ts @@ -0,0 +1,7 @@ +import { UnparsedObject } from "@datadog/datadog-api-client"; + +/** + * The JSON:API type for scorecard outcomes. + */ +export type UpdateOutcomesAsyncType = typeof BATCHED_OUTCOME | UnparsedObject; +export const BATCHED_OUTCOME = "batched-outcome";