1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-04-24 01:18:01 +02:00

chore: consider execution limits per minute and actions limit per (#6462)

## About the changes
Define a schema that works both for the frontend and the backend to
define soft limits in the resource usage.
This commit is contained in:
Gastón Fournier 2024-03-07 13:02:49 +01:00 committed by GitHub
parent 52d63bc726
commit 5b87ca6b75
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 121 additions and 2 deletions

View File

@ -182,6 +182,16 @@ exports[`should create default config 1`] = `
"passwordResetMaxPerMinute": 1,
"simpleLoginMaxPerMinute": 10,
},
"resourceLimits": {
"actionSetActions": 10,
"actionSetFilterValues": 25,
"actionSetFilters": 5,
"actionSetsPerProject": 5,
"segmentValues": 1000,
"signalEndpoints": 5,
"signalTokensPerEndpoint": 5,
"strategySegments": 5,
},
"secureHeaders": false,
"segmentValuesLimit": 1000,
"server": {

View File

@ -50,6 +50,7 @@ import {
} from './util/segments';
import FlagResolver from './util/flag-resolver';
import { validateOrigins } from './util/validateOrigin';
import { ResourceLimitsSchema } from './openapi/spec/resource-limits-schema';
const safeToUpper = (s?: string) => (s ? s.toUpperCase() : s);
@ -573,6 +574,35 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
91,
);
const resourceLimits: ResourceLimitsSchema = {
segmentValues: segmentValuesLimit,
strategySegments: strategySegmentsLimit,
signalEndpoints: parseEnvVarNumber(
process.env.UNLEASH_SIGNAL_ENDPOINTS_LIMIT,
5,
),
actionSetActions: parseEnvVarNumber(
process.env.UNLEASH_ACTION_SET_ACTIONS_LIMIT,
10,
),
actionSetsPerProject: parseEnvVarNumber(
process.env.UNLEASH_ACTION_SETS_PER_PROJECT_LIMIT,
5,
),
actionSetFilters: parseEnvVarNumber(
process.env.UNLEASH_ACTION_SET_FILTERS_LIMIT,
5,
),
actionSetFilterValues: parseEnvVarNumber(
process.env.UNLEASH_ACTION_SET_FILTER_VALUES_LIMIT,
25,
),
signalTokensPerEndpoint: parseEnvVarNumber(
process.env.UNLEASH_SIGNAL_TOKENS_PER_ENDPOINT_LIMIT,
5,
),
};
return {
db,
session,
@ -600,6 +630,7 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
inlineSegmentConstraints,
segmentValuesLimit,
strategySegmentsLimit,
resourceLimits,
clientFeatureCaching,
accessControlMaxAge,
prometheusApi,

View File

@ -126,6 +126,7 @@ import {
requestsPerSecondSchema,
requestsPerSecondSegmentedSchema,
resetPasswordSchema,
resourceLimitsSchema,
roleSchema,
sdkContextSchema,
sdkFlatContextSchema,
@ -431,6 +432,7 @@ export const schemas: UnleashSchemas = {
inactiveUserSchema,
inactiveUsersSchema,
recordUiErrorSchema,
resourceLimitsSchema,
};
// Remove JSONSchema keys that would result in an invalid OpenAPI spec.

View File

@ -179,3 +179,4 @@ export * from './record-ui-error-schema';
export * from './project-application-schema';
export * from './project-applications-schema';
export * from './application-environment-instances-schema';
export * from './resource-limits-schema';

View File

@ -0,0 +1,58 @@
import { FromSchema } from 'json-schema-to-ts';
export const resourceLimitsSchema = {
$id: '#/components/schemas/resourceLimitsSchema',
type: 'object',
description: 'A map of resource names and their limits.',
additionalProperties: false,
properties: {
segmentValues: {
type: 'number',
example: 10,
description: 'The maximum number of values per segment allowed.',
},
strategySegments: {
type: 'number',
example: 10,
description: 'The maximum number of strategy segments allowed.',
},
actionSetActions: {
type: 'number',
example: 10,
description:
'The maximum number of actions per action set allowed.',
},
actionSetsPerProject: {
type: 'number',
example: 10,
description:
'The maximum number of action set definitions per project allowed.',
},
actionSetFilters: {
type: 'number',
example: 10,
description:
'The maximum number of filters per action set allowed.',
},
actionSetFilterValues: {
type: 'number',
example: 10,
description:
'The maximum number of filter values inside an action set allowed.',
},
signalEndpoints: {
type: 'number',
example: 10,
description: 'The maximum number of signal endpoints allowed.',
},
signalTokensPerEndpoint: {
type: 'number',
example: 10,
description:
'The maximum number of signal tokens per endpoint allowed.',
},
},
components: {},
} as const;
export type ResourceLimitsSchema = FromSchema<typeof resourceLimitsSchema>;

View File

@ -1,6 +1,7 @@
import { FromSchema } from 'json-schema-to-ts';
import { versionSchema } from './version-schema';
import { variantFlagSchema } from './variant-flag-schema';
import { resourceLimitsSchema } from './resource-limits-schema';
export const uiConfigSchema = {
$id: '#/components/schemas/uiConfigSchema',
@ -70,12 +71,22 @@ export const uiConfigSchema = {
description:
'The maximum number of values that can be used in a single segment.',
example: 1000,
deprecated: true,
},
strategySegmentsLimit: {
type: 'number',
description:
'The maximum number of segments that can be applied to a single strategy.',
example: 5,
deprecated: true,
},
resourceLimits: {
$ref: resourceLimitsSchema.$id,
description: resourceLimitsSchema.description,
example: {
segmentValues: 100,
strategySegments: 5,
},
},
networkViewEnabled: {
type: 'boolean',
@ -157,6 +168,7 @@ export const uiConfigSchema = {
schemas: {
versionSchema,
variantFlagSchema,
resourceLimitsSchema,
},
},
} as const;

View File

@ -166,11 +166,12 @@ class ConfigController extends Controller {
unleashUrl: this.config.server.unleashUrl,
baseUriPath: this.config.server.baseUriPath,
authenticationType: this.config.authentication?.type,
segmentValuesLimit: this.config.segmentValuesLimit,
strategySegmentsLimit: this.config.strategySegmentsLimit,
segmentValuesLimit: this.config.resourceLimits.segmentValues,
strategySegmentsLimit: this.config.resourceLimits.strategySegments,
frontendApiOrigins: frontendSettings.frontendApiOrigins,
versionInfo: await this.versionService.getVersionInfo(),
networkViewEnabled: this.config.prometheusApi !== undefined,
resourceLimits: this.config.resourceLimits,
disablePasswordAuth,
maintenanceMode,
feedbackUriPath: this.config.feedbackUriPath,

View File

@ -5,6 +5,7 @@ import { ILegacyApiTokenCreate } from './models/api-token';
import { IFlagResolver, IExperimentalOptions, IFlags } from './experimental';
import SMTPTransport from 'nodemailer/lib/smtp-transport';
import { IUnleashServices } from './services';
import { ResourceLimitsSchema } from '../openapi/spec/resource-limits-schema';
export interface ISSLOption {
rejectUnauthorized: boolean;
@ -235,8 +236,11 @@ export interface IUnleashConfig {
environmentEnableOverrides?: string[];
frontendApi: IFrontendApi;
inlineSegmentConstraints: boolean;
/** @deprecated: use resourceLimits.segmentValues */
segmentValuesLimit: number;
/** @deprecated: use resourceLimits.strategySegments */
strategySegmentsLimit: number;
resourceLimits: ResourceLimitsSchema;
metricsRateLimiting: IMetricsRateLimiting;
dailyMetricsStorageDays: number;
clientFeatureCaching: IClientCachingOption;