mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-29 01:15:48 +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:
parent
52d63bc726
commit
5b87ca6b75
@ -182,6 +182,16 @@ exports[`should create default config 1`] = `
|
|||||||
"passwordResetMaxPerMinute": 1,
|
"passwordResetMaxPerMinute": 1,
|
||||||
"simpleLoginMaxPerMinute": 10,
|
"simpleLoginMaxPerMinute": 10,
|
||||||
},
|
},
|
||||||
|
"resourceLimits": {
|
||||||
|
"actionSetActions": 10,
|
||||||
|
"actionSetFilterValues": 25,
|
||||||
|
"actionSetFilters": 5,
|
||||||
|
"actionSetsPerProject": 5,
|
||||||
|
"segmentValues": 1000,
|
||||||
|
"signalEndpoints": 5,
|
||||||
|
"signalTokensPerEndpoint": 5,
|
||||||
|
"strategySegments": 5,
|
||||||
|
},
|
||||||
"secureHeaders": false,
|
"secureHeaders": false,
|
||||||
"segmentValuesLimit": 1000,
|
"segmentValuesLimit": 1000,
|
||||||
"server": {
|
"server": {
|
||||||
|
@ -50,6 +50,7 @@ import {
|
|||||||
} from './util/segments';
|
} from './util/segments';
|
||||||
import FlagResolver from './util/flag-resolver';
|
import FlagResolver from './util/flag-resolver';
|
||||||
import { validateOrigins } from './util/validateOrigin';
|
import { validateOrigins } from './util/validateOrigin';
|
||||||
|
import { ResourceLimitsSchema } from './openapi/spec/resource-limits-schema';
|
||||||
|
|
||||||
const safeToUpper = (s?: string) => (s ? s.toUpperCase() : s);
|
const safeToUpper = (s?: string) => (s ? s.toUpperCase() : s);
|
||||||
|
|
||||||
@ -573,6 +574,35 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
|||||||
91,
|
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 {
|
return {
|
||||||
db,
|
db,
|
||||||
session,
|
session,
|
||||||
@ -600,6 +630,7 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
|||||||
inlineSegmentConstraints,
|
inlineSegmentConstraints,
|
||||||
segmentValuesLimit,
|
segmentValuesLimit,
|
||||||
strategySegmentsLimit,
|
strategySegmentsLimit,
|
||||||
|
resourceLimits,
|
||||||
clientFeatureCaching,
|
clientFeatureCaching,
|
||||||
accessControlMaxAge,
|
accessControlMaxAge,
|
||||||
prometheusApi,
|
prometheusApi,
|
||||||
|
@ -126,6 +126,7 @@ import {
|
|||||||
requestsPerSecondSchema,
|
requestsPerSecondSchema,
|
||||||
requestsPerSecondSegmentedSchema,
|
requestsPerSecondSegmentedSchema,
|
||||||
resetPasswordSchema,
|
resetPasswordSchema,
|
||||||
|
resourceLimitsSchema,
|
||||||
roleSchema,
|
roleSchema,
|
||||||
sdkContextSchema,
|
sdkContextSchema,
|
||||||
sdkFlatContextSchema,
|
sdkFlatContextSchema,
|
||||||
@ -431,6 +432,7 @@ export const schemas: UnleashSchemas = {
|
|||||||
inactiveUserSchema,
|
inactiveUserSchema,
|
||||||
inactiveUsersSchema,
|
inactiveUsersSchema,
|
||||||
recordUiErrorSchema,
|
recordUiErrorSchema,
|
||||||
|
resourceLimitsSchema,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Remove JSONSchema keys that would result in an invalid OpenAPI spec.
|
// Remove JSONSchema keys that would result in an invalid OpenAPI spec.
|
||||||
|
@ -179,3 +179,4 @@ export * from './record-ui-error-schema';
|
|||||||
export * from './project-application-schema';
|
export * from './project-application-schema';
|
||||||
export * from './project-applications-schema';
|
export * from './project-applications-schema';
|
||||||
export * from './application-environment-instances-schema';
|
export * from './application-environment-instances-schema';
|
||||||
|
export * from './resource-limits-schema';
|
||||||
|
58
src/lib/openapi/spec/resource-limits-schema.ts
Normal file
58
src/lib/openapi/spec/resource-limits-schema.ts
Normal 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>;
|
@ -1,6 +1,7 @@
|
|||||||
import { FromSchema } from 'json-schema-to-ts';
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
import { versionSchema } from './version-schema';
|
import { versionSchema } from './version-schema';
|
||||||
import { variantFlagSchema } from './variant-flag-schema';
|
import { variantFlagSchema } from './variant-flag-schema';
|
||||||
|
import { resourceLimitsSchema } from './resource-limits-schema';
|
||||||
|
|
||||||
export const uiConfigSchema = {
|
export const uiConfigSchema = {
|
||||||
$id: '#/components/schemas/uiConfigSchema',
|
$id: '#/components/schemas/uiConfigSchema',
|
||||||
@ -70,12 +71,22 @@ export const uiConfigSchema = {
|
|||||||
description:
|
description:
|
||||||
'The maximum number of values that can be used in a single segment.',
|
'The maximum number of values that can be used in a single segment.',
|
||||||
example: 1000,
|
example: 1000,
|
||||||
|
deprecated: true,
|
||||||
},
|
},
|
||||||
strategySegmentsLimit: {
|
strategySegmentsLimit: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
description:
|
description:
|
||||||
'The maximum number of segments that can be applied to a single strategy.',
|
'The maximum number of segments that can be applied to a single strategy.',
|
||||||
example: 5,
|
example: 5,
|
||||||
|
deprecated: true,
|
||||||
|
},
|
||||||
|
resourceLimits: {
|
||||||
|
$ref: resourceLimitsSchema.$id,
|
||||||
|
description: resourceLimitsSchema.description,
|
||||||
|
example: {
|
||||||
|
segmentValues: 100,
|
||||||
|
strategySegments: 5,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
networkViewEnabled: {
|
networkViewEnabled: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
@ -157,6 +168,7 @@ export const uiConfigSchema = {
|
|||||||
schemas: {
|
schemas: {
|
||||||
versionSchema,
|
versionSchema,
|
||||||
variantFlagSchema,
|
variantFlagSchema,
|
||||||
|
resourceLimitsSchema,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -166,11 +166,12 @@ class ConfigController extends Controller {
|
|||||||
unleashUrl: this.config.server.unleashUrl,
|
unleashUrl: this.config.server.unleashUrl,
|
||||||
baseUriPath: this.config.server.baseUriPath,
|
baseUriPath: this.config.server.baseUriPath,
|
||||||
authenticationType: this.config.authentication?.type,
|
authenticationType: this.config.authentication?.type,
|
||||||
segmentValuesLimit: this.config.segmentValuesLimit,
|
segmentValuesLimit: this.config.resourceLimits.segmentValues,
|
||||||
strategySegmentsLimit: this.config.strategySegmentsLimit,
|
strategySegmentsLimit: this.config.resourceLimits.strategySegments,
|
||||||
frontendApiOrigins: frontendSettings.frontendApiOrigins,
|
frontendApiOrigins: frontendSettings.frontendApiOrigins,
|
||||||
versionInfo: await this.versionService.getVersionInfo(),
|
versionInfo: await this.versionService.getVersionInfo(),
|
||||||
networkViewEnabled: this.config.prometheusApi !== undefined,
|
networkViewEnabled: this.config.prometheusApi !== undefined,
|
||||||
|
resourceLimits: this.config.resourceLimits,
|
||||||
disablePasswordAuth,
|
disablePasswordAuth,
|
||||||
maintenanceMode,
|
maintenanceMode,
|
||||||
feedbackUriPath: this.config.feedbackUriPath,
|
feedbackUriPath: this.config.feedbackUriPath,
|
||||||
|
@ -5,6 +5,7 @@ import { ILegacyApiTokenCreate } from './models/api-token';
|
|||||||
import { IFlagResolver, IExperimentalOptions, IFlags } from './experimental';
|
import { IFlagResolver, IExperimentalOptions, IFlags } from './experimental';
|
||||||
import SMTPTransport from 'nodemailer/lib/smtp-transport';
|
import SMTPTransport from 'nodemailer/lib/smtp-transport';
|
||||||
import { IUnleashServices } from './services';
|
import { IUnleashServices } from './services';
|
||||||
|
import { ResourceLimitsSchema } from '../openapi/spec/resource-limits-schema';
|
||||||
|
|
||||||
export interface ISSLOption {
|
export interface ISSLOption {
|
||||||
rejectUnauthorized: boolean;
|
rejectUnauthorized: boolean;
|
||||||
@ -235,8 +236,11 @@ export interface IUnleashConfig {
|
|||||||
environmentEnableOverrides?: string[];
|
environmentEnableOverrides?: string[];
|
||||||
frontendApi: IFrontendApi;
|
frontendApi: IFrontendApi;
|
||||||
inlineSegmentConstraints: boolean;
|
inlineSegmentConstraints: boolean;
|
||||||
|
/** @deprecated: use resourceLimits.segmentValues */
|
||||||
segmentValuesLimit: number;
|
segmentValuesLimit: number;
|
||||||
|
/** @deprecated: use resourceLimits.strategySegments */
|
||||||
strategySegmentsLimit: number;
|
strategySegmentsLimit: number;
|
||||||
|
resourceLimits: ResourceLimitsSchema;
|
||||||
metricsRateLimiting: IMetricsRateLimiting;
|
metricsRateLimiting: IMetricsRateLimiting;
|
||||||
dailyMetricsStorageDays: number;
|
dailyMetricsStorageDays: number;
|
||||||
clientFeatureCaching: IClientCachingOption;
|
clientFeatureCaching: IClientCachingOption;
|
||||||
|
Loading…
Reference in New Issue
Block a user