diff --git a/apps/cli-e2e/src/support/test-setup.ts b/apps/cli-e2e/src/support/test-setup.ts index 2f1d8f6..a113e6e 100644 --- a/apps/cli-e2e/src/support/test-setup.ts +++ b/apps/cli-e2e/src/support/test-setup.ts @@ -1,23 +1,23 @@ /* eslint-disable */ -import _ from "lodash" import axios from 'axios'; -import { stringify, parse } from "qs"; +import _ from 'lodash'; +import { parse, stringify } from 'qs'; module.exports = async function () { // Configure axios for tests to use. // const host = process.env.HOST ?? 'localhost'; // const port = process.env.PORT ?? '3000'; axios.defaults.paramsSerializer = { - encode: parse, - serialize: stringify - } + encode: (params) => parse(params), + serialize: (params) => stringify(params), + }; axios.defaults.baseURL = process.env.API7EE_SERVER_URL; axios.interceptors.response.use( (response) => response, (error) => { console.log('error: ', error); - if (!error?.request) return + if (!error?.request) return; const picked = _.pick(error.request, [ 'outputData', @@ -39,12 +39,12 @@ module.exports = async function () { 'config', '_header', '_keepAliveTimeout', - ]) - error.request = picked + ]); + error.request = picked; if (error.response?.request) { - error.response.request = picked + error.response.request = picked; } - return error + return error; }, - ) + ); }; diff --git a/apps/cli/src/command/diff.command.ts b/apps/cli/src/command/diff.command.ts index 549bf1f..d40ded5 100644 --- a/apps/cli/src/command/diff.command.ts +++ b/apps/cli/src/command/diff.command.ts @@ -139,30 +139,15 @@ export const DiffResourceTask = ( ctx.diff.forEach((event) => { switch (event.type) { case ADCSDK.EventType.CREATE: - task.output += `create ${ - event.resourceType - }: "${ADCSDK.getResourceName( - event.resourceType, - event.newValue, - )}"\n`; + task.output += `create ${event.resourceType}: "${event.resourceName}"\n`; created++; break; case ADCSDK.EventType.DELETE: - task.output += `delete ${ - event.resourceType - }: "${ADCSDK.getResourceName( - event.resourceType, - event.oldValue, - )}"\n`; + task.output += `delete ${event.resourceType}: "${event.resourceName}"\n`; deleted++; break; case ADCSDK.EventType.UPDATE: - task.output += `update ${ - event.resourceType - }: "${ADCSDK.getResourceName( - event.resourceType, - event.newValue, - )}"\n`; + task.output += `update ${event.resourceType}: "${event.resourceName}"\n`; updated++; break; } diff --git a/apps/cli/src/differ/differv2.ts b/apps/cli/src/differ/differv2.ts index 93e82ce..c9623d6 100644 --- a/apps/cli/src/differ/differv2.ts +++ b/apps/cli/src/differ/differv2.ts @@ -191,6 +191,21 @@ export class DifferV2 { } } + /** + * Check resource changes for + * - route(name) + * - service(name) + * - upstream(name) + * - ssl(snis.join(',')) + * - plugin_configs(name) + * - consumers(username) + * - consumer_groups(name) + * - stream_routes(name) + * @param resourceType + * @param local + * @param remote + * @returns + */ private diffResource( resourceType: ADCSDK.EventResourceType, local: Record = {}, @@ -200,11 +215,23 @@ export class DifferV2 { // temporarily stores checked remote resource ids for identifying new resources to added const checkedId: Array = []; + const nameExtractor = ( + resource: ADCSDK.Event['newValue'], + fallback?: string, + ) => + resourceType === ADCSDK.EventResourceType.SSL + ? (resource as ADCSDK.SSL).snis.join(',') + : resourceType === ADCSDK.EventResourceType.CONSUMER + ? (resource as ADCSDK.Consumer).username + : (resource as { name: string }).name ?? fallback; //TODO optimize typing and fallbacks that should not exist (value source should be unique) // check each remote resources remote.forEach((remoteItem) => { const localId = DifferV2.getADCResourceId(resourceType, remoteItem); const localItem = local[localId]; + const resourceName = !localItem + ? nameExtractor(remoteItem) + : nameExtractor(localItem); // the local resource does not contain a remote resource, // which means that it should be deleted: send delete event @@ -215,6 +242,7 @@ export class DifferV2 { resourceType, type: ADCSDK.EventType.DELETE, resourceId: localId, + resourceName, oldValue: remoteItem, }); } @@ -255,6 +283,7 @@ export class DifferV2 { resourceType, type: ADCSDK.EventType.UPDATE, resourceId: localId, + resourceName, oldValue: remoteItem, newValue: localItem, // use local configuration to avoid turn back the remote old configuration to server-side diff: detailedDiff(mergedItem, remoteItem), @@ -273,6 +302,7 @@ export class DifferV2 { return result.push({ resourceType, resourceId: localId, + resourceName: nameExtractor(local[localId], localId), type: ADCSDK.EventType.CREATE, newValue: local[localId], }); @@ -309,6 +339,7 @@ export class DifferV2 { resourceType, type: ADCSDK.EventType.DELETE, resourceId: localId, + resourceName: remoteItem.name, oldValue: remoteItem, subEvents: new DifferV2() .diff( @@ -378,6 +409,7 @@ export class DifferV2 { ? ADCSDK.EventType.UPDATE : ADCSDK.EventType.ONLY_SUB_EVENTS, resourceId: localId, + resourceName: localServiceWithoutRoutes.name, oldValue: remoteServiceWithoutRoutes, newValue: localServiceWithoutRoutes, diff: detailedDiff( @@ -430,6 +462,7 @@ export class DifferV2 { ? ADCSDK.EventType.UPDATE : ADCSDK.EventType.ONLY_SUB_EVENTS, resourceId: localId, + resourceName: localConsumerGroupWithoutConsumers.name, oldValue: remoteConsumerGroupWithoutConsumers, newValue: localConsumerGroupWithoutConsumers, diff: detailedDiff( @@ -455,6 +488,7 @@ export class DifferV2 { return result.push({ resourceType, resourceId: localId, + resourceName: local[localId].name, type: ADCSDK.EventType.CREATE, newValue: local[localId], subEvents: new DifferV2() diff --git a/libs/sdk/src/core/differ.ts b/libs/sdk/src/core/differ.ts index 3cdc627..362d2a3 100644 --- a/libs/sdk/src/core/differ.ts +++ b/libs/sdk/src/core/differ.ts @@ -40,61 +40,62 @@ export interface EventDiff { export type Event = { type: EventType; resourceId: string; + resourceName: string; diff?: EventDiff; // for nested events parentId?: string; subEvents?: Array; } & ( - | { + | { resourceType: typeof EventResourceType.ROUTE; oldValue?: Route; newValue?: Route; } - | { + | { resourceType: EventResourceType.SERVICE; oldValue?: Service; newValue?: Service; } - | { + | { resourceType: EventResourceType.UPSTREAM; oldValue?: Upstream; newValue?: Upstream; } - | { + | { resourceType: EventResourceType.SSL; oldValue?: SSL; newValue?: SSL; } - | { + | { resourceType: EventResourceType.GLOBAL_RULE; oldValue?: GlobalRule; newValue?: GlobalRule; } - | { + | { resourceType: EventResourceType.PLUGIN_CONFIG; oldValue?: PluginConfig; newValue?: PluginConfig; } - | { + | { resourceType: EventResourceType.PLUGIN_METADATA; oldValue?: PluginMetadata; newValue?: PluginMetadata; pluginName: string; } - | { + | { resourceType: EventResourceType.CONSUMER; oldValue?: Consumer; newValue?: Consumer; } - | { + | { resourceType: EventResourceType.CONSUMER_GROUP; oldValue?: ConsumerGroup; newValue?: ConsumerGroup; } - | { + | { resourceType: EventResourceType.STREAM_ROUTE; oldValue?: StreamRoute; newValue?: StreamRoute; } - ); +); diff --git a/package.json b/package.json index 2294790..257e77b 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ }, "dependencies": { "@readme/openapi-parser": "^2.5.0", + "@types/qs": "^6.9.12", "axios": "^1.6.5", "chalk": "^4", "commander": "^11.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76c985e..15f06de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ dependencies: '@readme/openapi-parser': specifier: ^2.5.0 version: 2.5.0(openapi-types@12.1.3) + '@types/qs': + specifier: ^6.9.12 + version: 6.9.12 axios: specifier: ^1.6.5 version: 1.6.5 @@ -3237,7 +3240,7 @@ packages: resolution: {integrity: sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==} dependencies: '@types/node': 18.16.9 - '@types/qs': 6.9.11 + '@types/qs': 6.9.12 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 dev: true @@ -3247,7 +3250,7 @@ packages: dependencies: '@types/body-parser': 1.19.5 '@types/express-serve-static-core': 4.17.41 - '@types/qs': 6.9.11 + '@types/qs': 6.9.12 '@types/serve-static': 1.15.5 dev: true @@ -3327,9 +3330,8 @@ packages: resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} dev: true - /@types/qs@6.9.11: - resolution: {integrity: sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==} - dev: true + /@types/qs@6.9.12: + resolution: {integrity: sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==} /@types/range-parser@1.2.7: resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}