Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): looser name length #179

Merged
merged 11 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
if: contains(github.event.pull_request.labels.*.name, 'test/api7') || github.event_name == 'push'
strategy:
matrix:
version: [3.2.13.0, 3.2.14.5]
version: [3.2.14.6]
env:
BACKEND_API7_DOWNLOAD_URL: https://run.api7.ai/api7-ee/api7-ee-v${{ matrix.version }}.tar.gz
BACKEND_API7_LICENSE: ${{ secrets.BACKEND_API7_LICENSE }}
Expand Down
19 changes: 17 additions & 2 deletions apps/cli/src/differ/differv3.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as ADCSDK from '@api7/adc-sdk';
import { randomUUID } from 'crypto';
import { diff as objectDiff } from 'deep-diff';
import { cloneDeep, isEmpty, isEqual, isNil, unset } from 'lodash';
import { cloneDeep, has, isEmpty, isEqual, isNil, unset } from 'lodash';
import winston from 'winston';

const order = {
Expand Down Expand Up @@ -359,6 +359,20 @@ export class DifferV3 {
);
}

// Services will have two different default value rules depending on
// the type of route they contain, one for HTTP services and another
// for stream services.
// Therefore, before merging the default values, we should decide
// the default value table according to the type of service. This type
// is only used for merging default values, other processes still
// use the ResourceType.SERVICE type.
const resourceTypeForDefault =
resourceType != ADCSDK.ResourceType.SERVICE
? resourceType
: has(localItem, 'stream_routes')
? ADCSDK.ResourceType.INTERNAL_STREAM_SERVICE
: ADCSDK.ResourceType.SERVICE;

// Merges local resources into a table of default values for this type.
// The Admin API merges the default values specified in the schema into
// the data, so default values not contained in the local data will
Expand All @@ -368,7 +382,8 @@ export class DifferV3 {
// As such, each backend implementation needs to provide its table of
// default values, which merges the local resources to the defaults,
// just as the Admin API does.
const defaultValue = this.defaultValue?.core?.[resourceType] ?? {};
const defaultValue =
this.defaultValue?.core?.[resourceTypeForDefault] ?? {};
const mergedLocalItem = this.mergeDefault(
localItem,
cloneDeep(defaultValue),
Expand Down
5 changes: 4 additions & 1 deletion apps/cli/src/linter/schema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { z } from 'zod';

const nameSchema = z.string().min(1).max(100);
const nameSchema = z
.string()
.min(1)
.max(64 * 1024);
const descriptionSchema = z
.string()
.max(64 * 1024)
Expand Down
17 changes: 13 additions & 4 deletions apps/cli/src/linter/specs/common.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { check } from '../';
describe('Common Linter', () => {
const cases = [
{
name: 'should check description length (length <= 64 * 1024)',
name: 'should check name/description length (length <= 64 * 1024)',
input: {
services: [
{
name: 'test',
name: ''.padEnd(64 * 1024, '0'),
description: ''.padEnd(64 * 1024, '0'),
routes: [],
},
Expand All @@ -19,18 +19,27 @@ describe('Common Linter', () => {
errors: [],
},
{
name: 'should check description length (length > 64 * 1024)',
name: 'should check name/description length (length > 64 * 1024)',
input: {
services: [
{
name: 'test',
name: ''.padEnd(64 * 1024 + 1, '0'),
description: ''.padEnd(64 * 1024 + 1, '0'),
routes: [],
},
],
} as ADCSDK.Configuration,
expect: false,
errors: [
{
code: 'too_big',
exact: false,
inclusive: true,
maximum: 65536,
message: 'String must contain at most 65536 character(s)',
path: ['services', 0, 'name'],
type: 'string',
},
{
code: 'too_big',
exact: false,
Expand Down
28 changes: 17 additions & 11 deletions libs/backend-api7/e2e/misc.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import * as ADCSDK from '@api7/adc-sdk';
import { unset } from 'lodash';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';

import { BackendAPI7 } from '../src';
import {
createEvent,
deleteEvent,
dumpConfiguration,
syncEvents,
updateEvent,
} from './support/utils';

describe('Miscellaneous', () => {
Expand All @@ -24,10 +20,15 @@ describe('Miscellaneous', () => {
});
});

describe('Sync resources with the description greater than 256 bytes', () => {
const service1Name = 'service1';
const service1 = {
name: service1Name,
describe('Sync resources with the name/description greater than 256 bytes', () => {
const routeName = ''.padEnd(64 * 1024, '0'); // 65536 bytes
const serviceName = ''.padEnd(64 * 1024, '0'); // 65536 bytes
const route = {
name: routeName,
uris: ['/test'],
};
const service = {
name: serviceName,
description: ''.padEnd(64 * 1024, '0'), // 65536 bytes
upstream: {
scheme: 'https',
Expand All @@ -39,22 +40,27 @@ describe('Miscellaneous', () => {
},
],
},
routes: [route],
} as ADCSDK.Service;

it('Create services', async () =>
syncEvents(backend, [
createEvent(ADCSDK.ResourceType.SERVICE, service1Name, service1),
createEvent(ADCSDK.ResourceType.SERVICE, serviceName, service),
createEvent(ADCSDK.ResourceType.ROUTE, routeName, route, serviceName),
]));

it('Dump', async () => {
const result = (await dumpConfiguration(backend)) as ADCSDK.Configuration;
expect(result.services).toHaveLength(1);
expect(result.services[0]).toMatchObject(service1);
expect(result.services[0]).toMatchObject(service);
expect(result.services[0]).toMatchObject(service);
expect(result.services[0].routes[0]).toMatchObject(route);
});

it('Delete service', async () =>
syncEvents(backend, [
deleteEvent(ADCSDK.ResourceType.SERVICE, service1Name),
deleteEvent(ADCSDK.ResourceType.ROUTE, routeName, serviceName),
deleteEvent(ADCSDK.ResourceType.SERVICE, serviceName),
]));

it('Dump again', async () => {
Expand Down
1 change: 1 addition & 0 deletions libs/backend-api7/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export class BackendAPI7 implements ADCSDK.Backend {
switch (type) {
case ADCSDK.ResourceType.ROUTE:
return toADC.transformRoute;
case ADCSDK.ResourceType.INTERNAL_STREAM_SERVICE:
case ADCSDK.ResourceType.SERVICE:
return toADC.transformService;
case ADCSDK.ResourceType.SSL:
Expand Down
4 changes: 4 additions & 0 deletions libs/backend-apisix/src/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export class Fetcher {

private allTask(): Array<FetchTask> {
return Object.values(ADCSDK.ResourceType)
.filter(
(resourceType) =>
resourceType !== ADCSDK.ResourceType.INTERNAL_STREAM_SERVICE, // ignore internal only types
)
.map((resourceType): [ADCSDK.ResourceType, string] => [
resourceType,
resourceTypeToAPIName(resourceType),
Expand Down
3 changes: 3 additions & 0 deletions libs/sdk/src/core/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ export enum ResourceType {
CONSUMER = 'consumer',
CONSUMER_GROUP = 'consumer_group',
STREAM_ROUTE = 'stream_route',

// internal use only
INTERNAL_STREAM_SERVICE = 'stream_service',
}
2 changes: 1 addition & 1 deletion schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
"maxLength": 65536
},
"description": {
"type": "string",
Expand Down
Loading