From fed76ee6ee00a0895677adec8d12cca4f0f6b5af Mon Sep 17 00:00:00 2001 From: Zeping Bai Date: Fri, 27 Dec 2024 10:43:29 +0800 Subject: [PATCH] feat(api7): support route vars expr (#219) --- .github/workflows/e2e.yaml | 2 +- .../e2e/resources/route.e2e-spec.ts | 52 +++++++++++++++++++ libs/backend-api7/src/operator.ts | 4 +- libs/backend-api7/src/transformer.ts | 2 + libs/backend-api7/src/typing.ts | 2 + libs/sdk/src/core/index.ts | 2 +- 6 files changed, 61 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 337bc31..6918f32 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -53,7 +53,7 @@ jobs: if: contains(github.event.pull_request.labels.*.name, 'test/api7') || github.event_name == 'push' strategy: matrix: - version: [3.2.14.6, 3.2.15.2, 3.2.16.2] + version: [3.2.14.6, 3.2.15.2, 3.2.16.7, 3.3.2] env: BACKEND_API7_VERSION: ${{ matrix.version }} BACKEND_API7_DOWNLOAD_URL: https://run.api7.ai/api7-ee/api7-ee-v${{ matrix.version }}.tar.gz diff --git a/libs/backend-api7/e2e/resources/route.e2e-spec.ts b/libs/backend-api7/e2e/resources/route.e2e-spec.ts index 7bf0479..d60fac1 100644 --- a/libs/backend-api7/e2e/resources/route.e2e-spec.ts +++ b/libs/backend-api7/e2e/resources/route.e2e-spec.ts @@ -1,10 +1,13 @@ import * as ADCSDK from '@api7/adc-sdk'; +import { gte } from 'semver'; import { BackendAPI7 } from '../../src'; import { + conditionalDescribe, createEvent, deleteEvent, dumpConfiguration, + semverCondition, syncEvents, } from '../support/utils'; @@ -72,4 +75,53 @@ describe('Route E2E', () => { expect(result.services).toHaveLength(0); }); }); + + conditionalDescribe(semverCondition(gte, '3.2.16'))('Vars', () => { + const serviceName = 'test'; + const service = { + name: serviceName, + upstream: { + scheme: 'https', + nodes: [ + { + host: 'httpbin.org', + port: 443, + weight: 100, + }, + ], + }, + path_prefix: '/test', + strip_path_prefix: true, + } as ADCSDK.Service; + const route1Name = 'route1'; + const route1 = { + name: route1Name, + uris: ['/route1'], + vars: [['remote_addr', '==', '1.1.1.1']], + } as ADCSDK.Route; + + it('Create resources', async () => + syncEvents(backend, [ + createEvent(ADCSDK.ResourceType.SERVICE, serviceName, service), + createEvent(ADCSDK.ResourceType.ROUTE, route1Name, route1, serviceName), + ])); + + it('Dump', async () => { + const result = (await dumpConfiguration(backend)) as ADCSDK.Configuration; + expect(result.services).toHaveLength(1); + expect(result.services[0]).toMatchObject(service); + expect(result.services[0].routes).toHaveLength(1); + expect(result.services[0].routes[0]).toMatchObject(route1); + }); + + it('Delete', async () => + syncEvents(backend, [ + deleteEvent(ADCSDK.ResourceType.SERVICE, serviceName), + ])); + + it('Dump again (service should not exist)', async () => { + const result = (await dumpConfiguration(backend)) as ADCSDK.Configuration; + expect(result.services).toHaveLength(0); + }); + }); }); diff --git a/libs/backend-api7/src/operator.ts b/libs/backend-api7/src/operator.ts index 021e84d..473bd0d 100644 --- a/libs/backend-api7/src/operator.ts +++ b/libs/backend-api7/src/operator.ts @@ -1,7 +1,7 @@ import * as ADCSDK from '@api7/adc-sdk'; import { Axios, AxiosResponse } from 'axios'; import { ListrTask } from 'listr2'; -import { size } from 'lodash'; +import { size, unset } from 'lodash'; import { SemVer, gte as semVerGTE } from 'semver'; import { FromADC } from './transformer'; @@ -41,6 +41,8 @@ export class Operator { task.output = buildReqAndRespDebugOutput(resp); } else if (event.resourceType === ADCSDK.ResourceType.ROUTE) { // Create a route template instead of create route directly + const route = this.fromADC(event); + if (!semVerGTE(ctx.api7Version, '3.2.16')) unset(route, 'vars'); resp = await this.client.put( `/api/routes/template/${event.resourceId}`, this.fromADC(event), diff --git a/libs/backend-api7/src/transformer.ts b/libs/backend-api7/src/transformer.ts index 1e86ac0..ce36cc2 100644 --- a/libs/backend-api7/src/transformer.ts +++ b/libs/backend-api7/src/transformer.ts @@ -27,6 +27,7 @@ export class ToADC { plugins: route.plugins, priority: route.priority, timeout: route.timeout, + vars: route.vars, }); } @@ -148,6 +149,7 @@ export class FromADC { paths: route.uris, priority: route.priority, timeout: route.timeout, + vars: route.vars, }); } diff --git a/libs/backend-api7/src/typing.ts b/libs/backend-api7/src/typing.ts index edeed44..1132e4b 100644 --- a/libs/backend-api7/src/typing.ts +++ b/libs/backend-api7/src/typing.ts @@ -1,6 +1,7 @@ import { PluginMetadata as ADCPluginMetadata, Upstream as ADCUpstream, + Expr, Labels, Plugins, UpstreamBalancer, @@ -25,6 +26,7 @@ export interface Route { // matcher paths: Array; methods?: Array; + vars: Expr; // misc enable_websocket?: boolean; diff --git a/libs/sdk/src/core/index.ts b/libs/sdk/src/core/index.ts index 2104cad..c459fca 100644 --- a/libs/sdk/src/core/index.ts +++ b/libs/sdk/src/core/index.ts @@ -4,7 +4,7 @@ export * from './resource'; export type Labels = Record>; export type Plugin = Record; export type Plugins = Record; -export type Expr = Array>; +export type Expr = Array; export interface Route { id?: string;