Skip to content
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
101 changes: 101 additions & 0 deletions libs/backend-api7/e2e/stream-route-plugins.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import * as ADCSDK from '@api7/adc-sdk';
import { globalAgent as httpAgent } from 'node:http';

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

describe('Sync and Dump - stream route plugins', () => {
let backend: BackendAPI7;

beforeAll(() => {
backend = new BackendAPI7({
server: process.env.SERVER!,
token: process.env.TOKEN!,
tlsSkipVerify: true,
gatewayGroup: process.env.GATEWAY_GROUP,
cacheKey: 'default',
httpAgent,
httpsAgent: generateHTTPSAgent(),
});
});

// Regression: ToADC.transformStreamRoute used to drop the plugins field, so a
// dumped stream route always came back without plugins. The "Dump preserves the
// stream route plugins" assertion below fails on the buggy code and passes once
// plugins are mapped on the dump path.
describe('Stream route plugin round-trip and removal', () => {
const serviceName = 'stream-service';
const service = {
name: serviceName,
upstream: {
scheme: 'tcp',
nodes: [{ host: 'httpbin.org', port: 80, weight: 100 }],
},
} as ADCSDK.Service;

const streamRouteName = 'stream-route';
const plugins: ADCSDK.Plugins = {
'ip-restriction': { whitelist: ['127.0.0.0/24'] },
};
const streamRoute = {
name: streamRouteName,
plugins,
} as ADCSDK.StreamRoute;

it('Create stream service and stream route with plugins', async () =>
syncEvents(backend, [
createEvent(ADCSDK.ResourceType.SERVICE, serviceName, service),
createEvent(
ADCSDK.ResourceType.STREAM_ROUTE,
streamRouteName,
streamRoute,
serviceName,
),
]));

it('Dump preserves the stream route plugins', async () => {
const result = (await dumpConfiguration(backend)) as ADCSDK.Configuration;
const svc = result.services?.find(
(item: ADCSDK.Service) => item.name === serviceName,
);
expect(svc?.stream_routes).toHaveLength(1);
expect(svc?.stream_routes?.[0].plugins).toMatchObject(plugins);
});

it('Remove all plugins from the stream route', async () =>
syncEvents(backend, [
updateEvent(
ADCSDK.ResourceType.STREAM_ROUTE,
streamRouteName,
{ ...streamRoute, plugins: {} },
serviceName,
),
]));

it('Dump reflects the plugin removal', async () => {
const result = (await dumpConfiguration(backend)) as ADCSDK.Configuration;
const svc = result.services?.find(
(item: ADCSDK.Service) => item.name === serviceName,
);
expect(svc?.stream_routes).toHaveLength(1);
expect(svc?.stream_routes?.[0].plugins ?? {}).toEqual({});
});

it('Delete', async () =>
syncEvents(backend, [
deleteEvent(
ADCSDK.ResourceType.STREAM_ROUTE,
streamRouteName,
serviceName,
),
deleteEvent(ADCSDK.ResourceType.SERVICE, serviceName),
]));
});
});
1 change: 1 addition & 0 deletions libs/backend-api7/src/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class ToADC {
name: route.name,
description: route.desc,
labels: ToADC.transformLabels(route.labels),
plugins: route.plugins,
server_addr: route.server_addr,
server_port: route.server_port,
remote_addr: route.remote_addr,
Expand Down
43 changes: 43 additions & 0 deletions libs/backend-api7/test/transformer.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as ADCSDK from '@api7/adc-sdk';

import { FromADC, ToADC } from '../src/transformer';
import * as typing from '../src/typing';

describe('Transformer', () => {
describe('stream route plugins round-trip', () => {
const plugins: ADCSDK.Plugins = {
'ip-restriction': { blacklist: ['0.0.0.0/0'] },
};

it('FromADC.transformStreamRoute writes plugins', () => {
const out = new FromADC().transformStreamRoute(
{
id: 'sr1',
name: 'sr1',
description: 'desc',
plugins,
} as ADCSDK.StreamRoute,
'svc1',
);
expect(out.plugins).toEqual(plugins);
});

// Regression: ToADC.transformStreamRoute used to drop the plugins field, so
// dumping a stream route always returned it without plugins. The differ then
// could not detect plugin removal (local empty === remote empty), leaving
// stale stream-route plugins on the gateway.
it('ToADC.transformStreamRoute preserves plugins on dump', () => {
const out = new ToADC().transformStreamRoute({
id: 'sr1',
name: 'sr1',
desc: 'desc',
service_id: 'svc1',
stream_route_id: 'sr1',
plugins,
server_addr: '1.1.1.1',
server_port: 80,
} as typing.StreamRoute);
expect(out.plugins).toEqual(plugins);
});
});
});
Loading