1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-31 13:47:02 +02:00

openapi: update ui-config endpoints (#4280)

This commit is contained in:
Thomas Heartman 2023-07-19 17:18:47 +02:00 committed by GitHub
parent fc25bc6b82
commit 87cec6c9b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 119 additions and 12 deletions

View File

@ -100,15 +100,11 @@ const metaRules: Rule[] = [
'pushVariantsSchema', 'pushVariantsSchema',
'resetPasswordSchema', 'resetPasswordSchema',
'sdkContextSchema', 'sdkContextSchema',
'setUiConfigSchema',
'stateSchema', 'stateSchema',
'uiConfigSchema',
'upsertContextFieldSchema', 'upsertContextFieldSchema',
'upsertStrategySchema', 'upsertStrategySchema',
'usersGroupsBaseSchema', 'usersGroupsBaseSchema',
'validateEdgeTokensSchema', 'validateEdgeTokensSchema',
'variantFlagSchema',
'versionSchema',
'projectOverviewSchema', 'projectOverviewSchema',
], ],
}, },
@ -136,17 +132,13 @@ const metaRules: Rule[] = [
'playgroundStrategySchema', 'playgroundStrategySchema',
'pushVariantsSchema', 'pushVariantsSchema',
'resetPasswordSchema', 'resetPasswordSchema',
'setUiConfigSchema',
'sortOrderSchema', 'sortOrderSchema',
'uiConfigSchema',
'upsertContextFieldSchema', 'upsertContextFieldSchema',
'upsertStrategySchema', 'upsertStrategySchema',
'usersGroupsBaseSchema', 'usersGroupsBaseSchema',
'usersSearchSchema', 'usersSearchSchema',
'validateEdgeTokensSchema', 'validateEdgeTokensSchema',
'variantFlagSchema',
'variantsSchema', 'variantsSchema',
'versionSchema',
], ],
}, },
]; ];

View File

@ -4,13 +4,18 @@ export const setUiConfigSchema = {
$id: '#/components/schemas/setUiConfigSchema', $id: '#/components/schemas/setUiConfigSchema',
type: 'object', type: 'object',
additionalProperties: false, additionalProperties: false,
description: 'Unleash configuration settings affect the admin UI.',
properties: { properties: {
frontendSettings: { frontendSettings: {
type: 'object', type: 'object',
description: 'Settings related to the front-end API.',
additionalProperties: false, additionalProperties: false,
required: ['frontendApiOrigins'], required: ['frontendApiOrigins'],
properties: { properties: {
frontendApiOrigins: { frontendApiOrigins: {
description:
'The list of origins that the front-end API should accept requests from.',
example: ['*'],
type: 'array', type: 'array',
items: { type: 'string' }, items: { type: 'string' },
}, },

View File

@ -6,52 +6,96 @@ export const uiConfigSchema = {
$id: '#/components/schemas/uiConfigSchema', $id: '#/components/schemas/uiConfigSchema',
type: 'object', type: 'object',
additionalProperties: false, additionalProperties: false,
description:
'A collection of properties used to configure the Unleash Admin UI.',
required: ['version', 'unleashUrl', 'baseUriPath', 'versionInfo'], required: ['version', 'unleashUrl', 'baseUriPath', 'versionInfo'],
properties: { properties: {
slogan: { slogan: {
type: 'string', type: 'string',
description: 'The slogan to display in the UI footer.',
example: 'The enterprise-ready feature toggle service.',
}, },
name: { name: {
type: 'string', type: 'string',
description:
'The name of this Unleash instance. Used to build the text in the footer.',
example: 'Unleash enterprise',
}, },
version: { version: {
type: 'string', type: 'string',
description: 'The current version of Unleash',
example: '5.3.0-main',
}, },
environment: { environment: {
type: 'string', type: 'string',
description:
'What kind of Unleash instance it is: Enterprise, Pro, or Open source',
example: 'Enterprise',
}, },
unleashUrl: { unleashUrl: {
type: 'string', type: 'string',
description: 'The URL of the Unleash instance.',
example: 'https://unleash.mycompany.com/enterprise',
}, },
baseUriPath: { baseUriPath: {
type: 'string', type: 'string',
description:
'The base URI path at which this Unleash instance is listening.',
example: '/enterprise',
}, },
disablePasswordAuth: { disablePasswordAuth: {
type: 'boolean', type: 'boolean',
description:
'Whether password authentication should be disabled or not.',
example: false,
}, },
emailEnabled: { emailEnabled: {
type: 'boolean', type: 'boolean',
description: 'Whether this instance can send out emails or not.',
example: true,
}, },
maintenanceMode: { maintenanceMode: {
type: 'boolean', type: 'boolean',
description: 'Whether maintenance mode is currently active or not.',
example: false,
}, },
segmentValuesLimit: { segmentValuesLimit: {
type: 'number', type: 'number',
description:
'The maximum number of values that can be used in a single segment.',
example: 1000,
}, },
strategySegmentsLimit: { strategySegmentsLimit: {
type: 'number', type: 'number',
description:
'The maximum number of segments that can be applied to a single strategy.',
example: 5,
}, },
networkViewEnabled: { networkViewEnabled: {
type: 'boolean', type: 'boolean',
description: 'Whether to enable the Unleash network view or not.',
example: true,
}, },
frontendApiOrigins: { frontendApiOrigins: {
type: 'array', type: 'array',
description:
'The list of origins that the front-end API should accept requests from.',
example: ['*'],
items: { items: {
type: 'string', type: 'string',
}, },
}, },
flags: { flags: {
type: 'object', type: 'object',
description:
'Additional (largely experimental) features that are enabled in this Unleash instance.',
example: {
messageBanner: {
name: 'disabled',
enabled: false,
},
featuresExportImport: true,
},
additionalProperties: { additionalProperties: {
anyOf: [ anyOf: [
{ {
@ -64,6 +108,22 @@ export const uiConfigSchema = {
}, },
}, },
links: { links: {
description: 'Relevant links to use in the UI.',
example: [
{
value: 'Documentation',
icon: 'library_books',
href: 'https://docs.getunleash.io/docs',
title: 'User documentation',
},
{
value: 'GitHub',
icon: 'c_github',
href: 'https://github.com/Unleash/unleash',
title: 'Source code on GitHub',
},
],
'x-enforcer-exception-skip-codes': 'WSCH006', // allow additional properties in example (openapi enforcer)
type: 'array', type: 'array',
items: { items: {
type: 'object', type: 'object',
@ -71,6 +131,9 @@ export const uiConfigSchema = {
}, },
authenticationType: { authenticationType: {
type: 'string', type: 'string',
description:
'The type of authentication enabled for this Unleash instance',
example: 'enterprise',
enum: [ enum: [
'open-source', 'open-source',
'demo', 'demo',

View File

@ -4,22 +4,34 @@ export const variantFlagSchema = {
$id: '#/components/schemas/variantFlagSchema', $id: '#/components/schemas/variantFlagSchema',
type: 'object', type: 'object',
additionalProperties: false, additionalProperties: false,
description: 'A representation of an evaluated Unleash feature variant.',
properties: { properties: {
name: { name: {
description:
'The name of the variant. Will always be disabled if `enabled` is false.',
example: 'blue',
type: 'string', type: 'string',
}, },
enabled: { enabled: {
type: 'boolean', type: 'boolean',
description: 'Whether the variant is enabled or not.',
example: true,
}, },
payload: { payload: {
type: 'object', type: 'object',
description: 'Additional data associated with this variant.',
additionalProperties: false, additionalProperties: false,
properties: { properties: {
type: { type: {
description: 'The type of data contained.',
type: 'string', type: 'string',
enum: ['string', 'json', 'csv'],
example: 'json',
}, },
value: { value: {
description: 'The actual associated data',
type: 'string', type: 'string',
example: '{ "starter": "squirtle" }',
}, },
}, },
}, },

View File

@ -4,16 +4,24 @@ export const versionSchema = {
$id: '#/components/schemas/versionSchema', $id: '#/components/schemas/versionSchema',
type: 'object', type: 'object',
additionalProperties: false, additionalProperties: false,
required: ['current', 'latest', 'isLatest', 'instanceId'], description: 'Detailed information about an Unleash version',
required: ['current', 'latest', 'isLatest'],
properties: { properties: {
current: { current: {
type: 'object', type: 'object',
additionalProperties: false, additionalProperties: false,
description: 'The current version of Unleash.',
properties: { properties: {
oss: { oss: {
description:
'The OSS version used when building this Unleash instance, represented as a git revision belonging to the [main Unleash git repo](https://github.com/Unleash/unleash/)',
example: '5.3.0-main',
type: 'string', type: 'string',
}, },
enterprise: { enterprise: {
description:
'The Enterpris version of Unleash used to build this instance, represented as a git revision belonging to the [Unleash Enterprise](https://github.com/ivarconr/unleash-enterprise) repository. Will be an empty string if no enterprise version was used,',
example: '5.3.0-main+2105.45ed03c9',
type: 'string', type: 'string',
}, },
}, },
@ -21,20 +29,32 @@ export const versionSchema = {
latest: { latest: {
type: 'object', type: 'object',
additionalProperties: false, additionalProperties: false,
description:
'Information about the latest available Unleash releases. Will be an empty object if no data is available.',
properties: { properties: {
oss: { oss: {
description: 'The latest available OSS version of Unleash',
type: 'string', type: 'string',
example: '5.1.5',
}, },
enterprise: { enterprise: {
description:
'The latest available Enterprise version of Unleash',
type: 'string', type: 'string',
example: '5.1.5',
}, },
}, },
}, },
isLatest: { isLatest: {
type: 'boolean', type: 'boolean',
description:
'Whether the Unleash server is running the latest release (`true`) or if there are updates available (`false`)',
example: true,
}, },
instanceId: { instanceId: {
type: 'string', type: 'string',
description: 'The instance identifier of the Unleash instance',
example: '0d652a82-43db-4144-8e02-864b0b030710',
}, },
}, },
components: {}, components: {},

View File

@ -13,7 +13,7 @@ const ajv = new Ajv({
), ),
// example was superseded by examples in openapi 3.1, but we're still on 3.0, so // example was superseded by examples in openapi 3.1, but we're still on 3.0, so
// let's add it back in! // let's add it back in!
keywords: ['example'], keywords: ['example', 'x-enforcer-exception-skip-codes'],
formats: { formats: {
'date-time': true, 'date-time': true,
uri: true, uri: true,

View File

@ -75,6 +75,9 @@ class ConfigController extends Controller {
middleware: [ middleware: [
openApiService.validPath({ openApiService.validPath({
tags: ['Admin UI'], tags: ['Admin UI'],
summary: 'Get UI configuration',
description:
'Retrieves the full configuration used to set up the Unleash Admin UI.',
operationId: 'getUiConfig', operationId: 'getUiConfig',
responses: { responses: {
200: createResponseSchema('uiConfigSchema'), 200: createResponseSchema('uiConfigSchema'),
@ -91,6 +94,9 @@ class ConfigController extends Controller {
middleware: [ middleware: [
openApiService.validPath({ openApiService.validPath({
tags: ['Admin UI'], tags: ['Admin UI'],
summary: 'Set UI configuration',
description:
'Sets the UI configuration for this Unleash instance.',
operationId: 'setUiConfig', operationId: 'setUiConfig',
requestBody: createRequestSchema('setUiConfigSchema'), requestBody: createRequestSchema('setUiConfigSchema'),
responses: { 200: emptyResponse }, responses: { 200: emptyResponse },

View File

@ -1,5 +1,8 @@
import dbInit, { ITestDb } from '../../helpers/database-init'; import dbInit, { ITestDb } from '../../helpers/database-init';
import { IUnleashTest, setupApp } from '../../helpers/test-helper'; import {
IUnleashTest,
setupAppWithCustomConfig,
} from '../../helpers/test-helper';
import getLogger from '../../../fixtures/no-logger'; import getLogger from '../../../fixtures/no-logger';
import { simpleAuthSettingsKey } from '../../../../lib/types/settings/simple-auth-settings'; import { simpleAuthSettingsKey } from '../../../../lib/types/settings/simple-auth-settings';
import { randomId } from '../../../../lib/util/random-id'; import { randomId } from '../../../../lib/util/random-id';
@ -9,7 +12,13 @@ let app: IUnleashTest;
beforeAll(async () => { beforeAll(async () => {
db = await dbInit('config_api_serial', getLogger); db = await dbInit('config_api_serial', getLogger);
app = await setupApp(db.stores); app = await setupAppWithCustomConfig(db.stores, {
experimental: {
flags: {
strictSchemaValidation: true,
},
},
});
}); });
afterAll(async () => { afterAll(async () => {