diff --git a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.json b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.json index ca30e6b29ae49..11bf01c8a7328 100644 --- a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.json +++ b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.json @@ -1740,11 +1740,17 @@ "target": { "description": "the target objective between 0 and 1 excluded", "type": "number", + "minimum": 0, + "maximum": 100, + "exclusiveMinimum": true, + "exclusiveMaximum": true, "example": 0.99 }, "timesliceTarget": { "description": "the target objective for each slice when using a timeslices budgeting method", "type": "number", + "minimum": 0, + "maximum": 100, "example": 0.995 }, "timesliceWindow": { @@ -2472,4 +2478,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.yaml b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.yaml index dc9e74407726f..d099474448eae 100644 --- a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.yaml +++ b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.yaml @@ -1187,10 +1187,16 @@ components: target: description: the target objective between 0 and 1 excluded type: number + minimum: 0 + maximum: 100 + exclusiveMinimum: true + exclusiveMaximum: true example: 0.99 timesliceTarget: description: the target objective for each slice when using a timeslices budgeting method type: number + minimum: 0 + maximum: 100 example: 0.995 timesliceWindow: description: the duration of each slice when using a timeslices budgeting method, as {duraton}{unit} diff --git a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/components/schemas/objective.yaml b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/components/schemas/objective.yaml index e0272c5a04029..a7cc6ae3d181b 100644 --- a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/components/schemas/objective.yaml +++ b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/components/schemas/objective.yaml @@ -7,10 +7,16 @@ properties: target: description: the target objective between 0 and 1 excluded type: number + minimum: 0 + maximum: 100 + exclusiveMinimum: true + exclusiveMaximum: true example: 0.99 timesliceTarget: description: the target objective for each slice when using a timeslices budgeting method type: number + minimum: 0 + maximum: 100 example: 0.995 timesliceWindow: description: the duration of each slice when using a timeslices budgeting method, as {duraton}{unit} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_objective_section_timeslices.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_objective_section_timeslices.tsx index 12e2bbed94b7b..b6d0b527eaf13 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_objective_section_timeslices.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_objective_section_timeslices.tsx @@ -41,8 +41,8 @@ export function SloEditFormObjectiveSectionTimeslices() { defaultValue={95} rules={{ required: true, - min: 0.001, - max: 99.999, + min: 0, + max: 100, }} render={({ field: { ref, onChange, ...field }, fieldState }) => ( onChange(event.target.value)} /> diff --git a/x-pack/plugins/observability_solution/slo/server/domain/services/validate_slo.test.ts b/x-pack/plugins/observability_solution/slo/server/domain/services/validate_slo.test.ts index f4f8142e8986a..7a4a6fc40005b 100644 --- a/x-pack/plugins/observability_solution/slo/server/domain/services/validate_slo.test.ts +++ b/x-pack/plugins/observability_solution/slo/server/domain/services/validate_slo.test.ts @@ -132,12 +132,12 @@ describe('validateSLO', () => { expect(() => validateSLO(slo)).toThrowError('Invalid objective.timeslice_target'); }); - it("throws when 'objective.timeslice_target' is lte 0", () => { + it("throws when 'objective.timeslice_target' is lt 0", () => { const slo = createSLO({ budgetingMethod: 'timeslices', objective: { target: 0.95, - timesliceTarget: 0, + timesliceTarget: -0.00001, timesliceWindow: new Duration(1, DurationUnit.Minute), }, }); diff --git a/x-pack/plugins/observability_solution/slo/server/domain/services/validate_slo.ts b/x-pack/plugins/observability_solution/slo/server/domain/services/validate_slo.ts index d98e1a0ef40b6..fadf4ea08e6ea 100644 --- a/x-pack/plugins/observability_solution/slo/server/domain/services/validate_slo.ts +++ b/x-pack/plugins/observability_solution/slo/server/domain/services/validate_slo.ts @@ -27,7 +27,7 @@ export function validateSLO(slo: SLODefinition) { throw new IllegalArgumentError('Invalid id'); } - if (!isValidTargetNumber(slo.objective.target)) { + if (!isValidObjectiveTarget(slo.objective.target)) { throw new IllegalArgumentError('Invalid objective.target'); } @@ -48,7 +48,7 @@ export function validateSLO(slo: SLODefinition) { if (timeslicesBudgetingMethodSchema.is(slo.budgetingMethod)) { if ( slo.objective.timesliceTarget === undefined || - !isValidTargetNumber(slo.objective.timesliceTarget) + !isValidTimesliceTarget(slo.objective.timesliceTarget) ) { throw new IllegalArgumentError('Invalid objective.timeslice_target'); } @@ -80,10 +80,14 @@ function isValidId(id: string): boolean { return MIN_ID_LENGTH <= id.length && id.length <= MAX_ID_LENGTH; } -function isValidTargetNumber(value: number): boolean { +function isValidObjectiveTarget(value: number): boolean { return value > 0 && value < 1; } +function isValidTimesliceTarget(value: number): boolean { + return value >= 0 && value <= 1; +} + function isValidRollingTimeWindowDuration(duration: Duration): boolean { // 7, 30 or 90days accepted return duration.unit === DurationUnit.Day && [7, 30, 90].includes(duration.value);