Skip to content

Commit b72f153

Browse files
authored
feat(core): inject managed by label (#533)
1 parent 06d3943 commit b72f153

12 files changed

Lines changed: 163 additions & 5 deletions

apps/cli/src/command/diff.command.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export const DiffCommand = new BackendCommand<DiffOptions>(
6969
opts.labelSelector,
7070
opts.includeResourceType,
7171
opts.excludeResourceType,
72+
opts.managedByLabel,
7273
),
7374
opts.lint ? LintTask() : { task: () => undefined },
7475
!opts.remoteStateFile

apps/cli/src/command/helper.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,12 @@ export class BackendCommand<
207207
)
208208
.env('ADC_TLS_SKIP_VERIFY')
209209
.default(false),
210+
)
211+
.addOption(
212+
new Option(
213+
'--no-managed-by-label',
214+
'disable injecting the "managed-by=adc" label into synced resources',
215+
),
210216
);
211217
}
212218
}

apps/cli/src/command/ingress-sync.command.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export const IngressSyncCommand = new BackendCommand<SyncOption>('sync')
3131
opts.labelSelector,
3232
opts.includeResourceType,
3333
opts.excludeResourceType,
34+
opts.managedByLabel,
3435
),
3536
LintTask(),
3637
!opts.remoteStateFile

apps/cli/src/command/lint.command.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ export const LintCommand = new BaseCommand('lint')
2828
const opts = LintCommand.optsWithGlobals();
2929

3030
const tasks = new Listr(
31-
[LoadLocalConfigurationTask(opts.file, {}), LintTask()],
31+
[
32+
LoadLocalConfigurationTask(opts.file, {}, undefined, undefined, false),
33+
LintTask(),
34+
],
3235
{
3336
renderer: SignaleRenderer,
3437
rendererOptions: { verbose: opts.verbose },

apps/cli/src/command/sync.command.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export const SyncCommand = new BackendCommand<SyncOption>(
8585
opts.labelSelector,
8686
opts.includeResourceType,
8787
opts.excludeResourceType,
88+
opts.managedByLabel,
8889
),
8990
opts.lint ? LintTask() : { task: () => undefined },
9091
!opts.remoteStateFile

apps/cli/src/command/typing.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export type BackendOptions = {
1616
labelSelector?: Record<string, string>;
1717
includeResourceType?: Array<ADCSDK.ResourceType>;
1818
excludeResourceType?: Array<ADCSDK.ResourceType>;
19+
managedByLabel?: boolean;
1920
} & GlobalOptions;
2021

2122
export interface KVConfiguration {

apps/cli/src/command/utils.spec.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as ADCSDK from '@api7/adc-sdk';
22

33
import {
4+
MANAGED_BY_LABEL_KEY,
5+
MANAGED_BY_LABEL_VALUE,
46
fillLabels,
57
recursiveRemoveIdField,
68
recursiveReplaceEnvVars,
@@ -254,6 +256,120 @@ describe('CLI utils', () => {
254256
});
255257
});
256258

259+
it('should label local resources as managed by ADC, the same way fillLabels does for --label-selector', () => {
260+
expect(
261+
fillLabels(
262+
{
263+
services: [
264+
{
265+
name: 'Test Service',
266+
routes: [
267+
{
268+
name: 'Test Nested Route',
269+
uris: ['/test-nested'],
270+
},
271+
],
272+
stream_routes: [
273+
{
274+
name: 'Test Nested Stream Route',
275+
},
276+
],
277+
},
278+
],
279+
consumers: [{ username: 'alice', labels: { team: 'a' } }],
280+
} as ADCSDK.Configuration,
281+
{ [MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE },
282+
),
283+
).toEqual({
284+
services: [
285+
{
286+
name: 'Test Service',
287+
labels: { [MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE },
288+
routes: [
289+
{
290+
name: 'Test Nested Route',
291+
uris: ['/test-nested'],
292+
labels: { [MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE },
293+
},
294+
],
295+
stream_routes: [
296+
{
297+
name: 'Test Nested Stream Route',
298+
labels: { [MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE },
299+
},
300+
],
301+
},
302+
],
303+
consumers: [
304+
{
305+
username: 'alice',
306+
labels: { team: 'a', [MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE },
307+
},
308+
],
309+
});
310+
});
311+
312+
it('should overwrite an existing managed-by label with a different value, keeping other labels', () => {
313+
expect(
314+
fillLabels(
315+
{
316+
services: [
317+
{
318+
name: 'Test Service',
319+
labels: { team: 'a', [MANAGED_BY_LABEL_KEY]: 'something-else' },
320+
routes: [
321+
{
322+
name: 'Test Nested Route',
323+
uris: ['/test-nested'],
324+
labels: { [MANAGED_BY_LABEL_KEY]: 'something-else' },
325+
},
326+
],
327+
stream_routes: [
328+
{
329+
name: 'Test Nested Stream Route',
330+
labels: { [MANAGED_BY_LABEL_KEY]: 'something-else' },
331+
},
332+
],
333+
},
334+
],
335+
consumers: [
336+
{
337+
username: 'alice',
338+
labels: { [MANAGED_BY_LABEL_KEY]: 'something-else' },
339+
},
340+
],
341+
} as ADCSDK.Configuration,
342+
{ [MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE },
343+
),
344+
).toEqual({
345+
services: [
346+
{
347+
name: 'Test Service',
348+
labels: { team: 'a', [MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE },
349+
routes: [
350+
{
351+
name: 'Test Nested Route',
352+
uris: ['/test-nested'],
353+
labels: { [MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE },
354+
},
355+
],
356+
stream_routes: [
357+
{
358+
name: 'Test Nested Stream Route',
359+
labels: { [MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE },
360+
},
361+
],
362+
},
363+
],
364+
consumers: [
365+
{
366+
username: 'alice',
367+
labels: { [MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE },
368+
},
369+
],
370+
});
371+
});
372+
257373
describe('Environment Variables', () => {
258374
it('mock config', () => {
259375
const config: ADCSDK.Configuration = {

apps/cli/src/command/utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,12 @@ export const fillLabels = (
200200
return configuration;
201201
};
202202

203+
// Injected into local resources the same way --label-selector's fillLabels()
204+
// works, so it flows into every CREATE/UPDATE payload naturally without any
205+
// special-casing in the differ or the backend.
206+
export const MANAGED_BY_LABEL_KEY = 'managed-by';
207+
export const MANAGED_BY_LABEL_VALUE = 'adc';
208+
203209
export const filterResourceType = (
204210
config: ADCSDK.Configuration = {},
205211
includes?: Array<string>,

apps/cli/src/command/validate.command.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export const ValidateCommand = new BackendCommand<ValidateOptions>(
5656
opts.labelSelector,
5757
opts.includeResourceType,
5858
opts.excludeResourceType,
59+
opts.managedByLabel,
5960
),
6061
opts.lint ? LintTask() : { task: () => undefined },
6162
DiffResourceTask(),

apps/cli/src/tasks/load_local.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import { ListrTask } from 'listr2';
77
import path from 'node:path';
88

99
import type { TaskContext } from '../command/diff.command';
10-
1110
import {
11+
MANAGED_BY_LABEL_KEY,
12+
MANAGED_BY_LABEL_VALUE,
1213
fillLabels,
1314
filterResourceType,
1415
mergeKVConfigurations,
@@ -22,6 +23,7 @@ export const LoadLocalConfigurationTask = (
2223
labelSelector?: ADCSDK.BackendOptions['labelSelector'],
2324
includeResourceType?: Array<ADCSDK.ResourceType>,
2425
excludeResourceType?: Array<ADCSDK.ResourceType>,
26+
managedByLabel = true,
2527
): ListrTask<TaskContext> => ({
2628
title: `Load local configuration`,
2729
task: async (ctx, task) => {
@@ -87,7 +89,8 @@ export const LoadLocalConfigurationTask = (
8789
{
8890
title: 'Filter configuration resource type',
8991
enabled: () =>
90-
(includeResourceType?.length ?? 0) > 0 || (excludeResourceType?.length ?? 0) > 0,
92+
(includeResourceType?.length ?? 0) > 0 ||
93+
(excludeResourceType?.length ?? 0) > 0,
9194
task: () => {
9295
ctx.local = filterResourceType(
9396
ctx.local,
@@ -104,6 +107,14 @@ export const LoadLocalConfigurationTask = (
104107
fillLabels(ctx.local, labelSelector);
105108
},
106109
},
110+
{
111+
enabled: managedByLabel,
112+
task: async () => {
113+
fillLabels(ctx.local, {
114+
[MANAGED_BY_LABEL_KEY]: MANAGED_BY_LABEL_VALUE,
115+
});
116+
},
117+
},
107118
],
108119
{
109120
ctx: subCtx,

0 commit comments

Comments
 (0)