Skip to content

Commit

Permalink
feat(api7): support API-level label selector (#150)
Browse files Browse the repository at this point in the history
  • Loading branch information
bzp2010 committed Jul 19, 2024
1 parent 5884b6e commit fe6c086
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 14 deletions.
152 changes: 152 additions & 0 deletions libs/backend-api7/e2e/label-selector.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
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,
} from './support/utils';

describe('Label Selector', () => {
const commonBackendOpts = {
server: process.env.SERVER,
token: process.env.TOKEN,
tlsSkipVerify: true,
gatewayGroup: 'default',
};
let backend: BackendAPI7;

beforeAll(() => {
backend = new BackendAPI7(commonBackendOpts);
});

describe('Consumer', () => {
const consumer1Name = 'consumer1';
const consumer1 = {
username: consumer1Name,
labels: { team: '1' },
plugins: {
'key-auth': {
key: consumer1Name,
},
},
} as ADCSDK.Consumer;
const consumer2Name = 'consumer2';
const consumer2 = {
username: consumer2Name,
labels: { team: '2' },
plugins: {
'key-auth': {
key: consumer2Name,
},
},
} as ADCSDK.Consumer;

it('Create consumers', async () =>
syncEvents(backend, [
createEvent(ADCSDK.ResourceType.CONSUMER, consumer1Name, consumer1),
createEvent(ADCSDK.ResourceType.CONSUMER, consumer2Name, consumer2),
]));

it('Dump consumer whit label team = 1', async () => {
const backend = new BackendAPI7({
...commonBackendOpts,
labelSelector: { team: '1' }, // add custom label selector
});
const result = (await dumpConfiguration(backend)) as ADCSDK.Configuration;
expect(result.consumers).toHaveLength(1);
expect(result.consumers[0]).toMatchObject(consumer1);
});

it('Dump consumer whit label team = 2', async () => {
const backend = new BackendAPI7({
...commonBackendOpts,
labelSelector: { team: '2' }, // add custom label selector
});
const result = (await dumpConfiguration(backend)) as ADCSDK.Configuration;
expect(result.consumers).toHaveLength(1);
expect(result.consumers[0]).toMatchObject(consumer2);
});

it('Delete consumers', async () =>
syncEvents(backend, [
deleteEvent(ADCSDK.ResourceType.CONSUMER, consumer1Name),
deleteEvent(ADCSDK.ResourceType.CONSUMER, consumer2Name),
]));
});

describe('SSL', () => {
const certificates = [
{
certificate: readFileSync(
join(__dirname, 'assets/certs/test-ssl1.cer'),
).toString('utf-8'),
key: readFileSync(
join(__dirname, 'assets/certs/test-ssl1.key'),
).toString('utf-8'),
},
{
certificate: readFileSync(
join(__dirname, 'assets/certs/test-ssl2.cer'),
).toString('utf-8'),
key: readFileSync(
join(__dirname, 'assets/certs/test-ssl2.key'),
).toString('utf-8'),
},
];
const ssl1SNIs = ['ssl1-1.com', 'ssl1-2.com'];
const ssl1 = {
snis: ssl1SNIs,
labels: { team: '1' },
certificates: [certificates[0]],
} as ADCSDK.SSL;
const ssl2SNIs = ['ssl2-1.com', 'ssl2-2.com'];
const ssl2 = {
snis: ssl2SNIs,
labels: { team: '2' },
certificates: [certificates[1]],
} as ADCSDK.SSL;
const sslName = (snis: Array<string>) => snis.join(',');

const ssl1test = structuredClone(ssl1);
const ssl2test = structuredClone(ssl2);
unset(ssl1test, 'certificates.0.key');
unset(ssl2test, 'certificates.0.key');

it('Create ssls', async () =>
syncEvents(backend, [
createEvent(ADCSDK.ResourceType.SSL, sslName(ssl1SNIs), ssl1),
createEvent(ADCSDK.ResourceType.SSL, sslName(ssl2SNIs), ssl2),
]));

it('Dump consumer whit label team = 1', async () => {
const backend = new BackendAPI7({
...commonBackendOpts,
labelSelector: { team: '1' }, // add custom label selector
});
const result = (await dumpConfiguration(backend)) as ADCSDK.Configuration;
expect(result.ssls).toHaveLength(1);
expect(result.ssls[0]).toMatchObject(ssl1test);
});

it('Dump consumer whit label team = 2', async () => {
const backend = new BackendAPI7({
...commonBackendOpts,
labelSelector: { team: '2' }, // add custom label selector
});
const result = (await dumpConfiguration(backend)) as ADCSDK.Configuration;
expect(result.ssls).toHaveLength(1);
expect(result.ssls[0]).toMatchObject(ssl2test);
});

it('Delete ssls', async () =>
syncEvents(backend, [
deleteEvent(ADCSDK.ResourceType.SSL, sslName(ssl1SNIs)),
deleteEvent(ADCSDK.ResourceType.SSL, sslName(ssl2SNIs)),
]));
});
});
34 changes: 24 additions & 10 deletions libs/backend-api7/src/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ export class Fetcher {
const resp = await this.client.get<{ list: Array<typing.Consumer> }>(
'/apisix/admin/consumers',
{
params: { gateway_group_id: ctx.gatewayGroupId },
params: this.attachLabelSelector({
gateway_group_id: ctx.gatewayGroupId,
}),
},
);
task.output = buildReqAndRespDebugOutput(resp, 'Get consumers');
Expand All @@ -92,7 +94,9 @@ export class Fetcher {
const resp = await this.client.get<{ list: Array<typing.SSL> }>(
'/apisix/admin/ssls',
{
params: { gateway_group_id: ctx.gatewayGroupId },
params: this.attachLabelSelector({
gateway_group_id: ctx.gatewayGroupId,
}),
},
);
task.output = buildReqAndRespDebugOutput(resp, 'Get ssls');
Expand Down Expand Up @@ -169,6 +173,16 @@ export class Fetcher {
};
}

public allTask() {
return [
this.listServices(),
this.listConsumers(),
this.listSSLs(),
this.listGlobalRules(),
this.listMetadatas(),
];
}

private isSkip(
requiredTypes: Array<ADCSDK.ResourceType>,
): () => string | undefined {
Expand All @@ -194,13 +208,13 @@ export class Fetcher {
};
}

public allTask() {
return [
this.listServices(),
this.listConsumers(),
this.listSSLs(),
this.listGlobalRules(),
this.listMetadatas(),
];
private attachLabelSelector(
params: Record<string, string>,
): Record<string, string> {
if (this.backendOpts?.labelSelector)
Object.entries(this.backendOpts.labelSelector).forEach(([key, value]) => {
params[`labels[${key}]`] = value;
});
return params;
}
}
4 changes: 2 additions & 2 deletions libs/backend-api7/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AxiosResponse } from 'axios';
import axios, { AxiosResponse } from 'axios';

export const capitalizeFirstLetter = (str: string) =>
str.charAt(0).toUpperCase() + str.slice(1);
Expand All @@ -24,7 +24,7 @@ export const buildReqAndRespDebugOutput = (
messages: [
`${desc ?? ''}\n`, //TODO time consumption
// request
`${config.method.toUpperCase()} ${config.url}\n`,
`${config.method.toUpperCase()} ${axios.getUri(config)}\n`,
...transformHeaders(config.headers),
config?.data ? `\n${config.data}\n` : '',
'\n',
Expand Down
4 changes: 2 additions & 2 deletions libs/backend-apisix/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as ADCSDK from '@api7/adc-sdk';
import { AxiosResponse } from 'axios';
import axios, { AxiosResponse } from 'axios';

export const resourceTypeToAPIName = (resourceType: ADCSDK.ResourceType) =>
resourceType !== ADCSDK.ResourceType.PLUGIN_METADATA
Expand Down Expand Up @@ -30,7 +30,7 @@ export const buildReqAndRespDebugOutput = (
messages: [
`${desc ?? ''}\n`, //TODO time consumption
// request
`${config.method.toUpperCase()} ${config.url}\n`,
`${config.method.toUpperCase()} ${axios.getUri(config)}\n`,
...transformHeaders(config.headers),
config?.data ? `\n${config.data}\n` : '',
'\n',
Expand Down

0 comments on commit fe6c086

Please sign in to comment.