From d3a9dd784c9479d8d1e4b33cc61cf524317e0c54 Mon Sep 17 00:00:00 2001 From: Zeping Bai Date: Fri, 24 Jan 2025 10:28:47 +0800 Subject: [PATCH] feat(core): add remote state file as experimental feature (#229) --- apps/cli/src/command/diff.command.ts | 27 +++++++++++++++++++++------ apps/cli/src/command/index.ts | 14 +++++++++++++- apps/cli/src/command/sync.command.ts | 18 ++++++++++++------ 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/apps/cli/src/command/diff.command.ts b/apps/cli/src/command/diff.command.ts index ee3b3db..13c7203 100644 --- a/apps/cli/src/command/diff.command.ts +++ b/apps/cli/src/command/diff.command.ts @@ -25,6 +25,9 @@ import { type DiffOptions = BackendOptions & { file: Array; lint: boolean; + + // experimental feature + remoteStateFile: string; }; export interface TaskContext { @@ -34,6 +37,16 @@ export interface TaskContext { defaultValue?: ADCSDK.DefaultValue; } +export const ExperimentalRemoteStateFileTask = (file: string) => ({ + task: async (ctx) => { + const fileContent = + (await readFile(file, { + encoding: 'utf-8', + })) ?? ''; + ctx.remote = YAML.parse(fileContent); + }, +}); + export const LoadLocalConfigurationTask = ( files: Array, labelSelector?: BackendOptions['labelSelector'], @@ -200,12 +213,14 @@ export const DiffCommand = new BackendCommand( opts.excludeResourceType, ), opts.lint ? LintTask() : { task: () => undefined }, - LoadRemoteConfigurationTask({ - backend, - labelSelector: opts.labelSelector, - includeResourceType: opts.includeResourceType, - excludeResourceType: opts.excludeResourceType, - }), + !opts.remoteStateFile + ? LoadRemoteConfigurationTask({ + backend, + labelSelector: opts.labelSelector, + includeResourceType: opts.includeResourceType, + excludeResourceType: opts.excludeResourceType, + }) + : ExperimentalRemoteStateFileTask(opts.remoteStateFile), DiffResourceTask(true, true), { title: 'Write detail diff result to file', diff --git a/apps/cli/src/command/index.ts b/apps/cli/src/command/index.ts index 6d8763a..b9877fa 100644 --- a/apps/cli/src/command/index.ts +++ b/apps/cli/src/command/index.ts @@ -14,11 +14,23 @@ export const setupCommands = (): Command => { const program = new Command('adc'); program - .description('API Declarative CLI (ADC) is a utility to manage API7 Enterprise and Apache APISIX declaratively.\n\nLearn more at: https://docs.api7.ai/enterprise/reference/adc') + .description( + 'API Declarative CLI (ADC) is a utility to manage API7 Enterprise and Apache APISIX declaratively.\n\nLearn more at: https://docs.api7.ai/enterprise/reference/adc', + ) .configureHelp({ showGlobalOptions: true }) .passThroughOptions() .version('0.17.0', '-v, --version', 'display ADC version'); + if ( + process.env.ADC_EXPERIMENTAL_FEATURE_FLAGS && + process.env.ADC_EXPERIMENTAL_FEATURE_FLAGS.includes('remote-state-file') + ) { + const desc = + 'path of the remote state file, which will allow the ADC to skip the initial dump process and use the ADC configuration contained in the remote state file directly'; + DiffCommand.option('--remote-state-file ', desc); + SyncCommand.option('--remote-state-file ', desc); + } + program .addCommand(PingCommand) .addCommand(DumpCommand) diff --git a/apps/cli/src/command/sync.command.ts b/apps/cli/src/command/sync.command.ts index d91b81c..ff6abfc 100644 --- a/apps/cli/src/command/sync.command.ts +++ b/apps/cli/src/command/sync.command.ts @@ -3,6 +3,7 @@ import { Listr } from 'listr2'; import { SignaleRenderer } from '../utils/listr'; import { DiffResourceTask, + ExperimentalRemoteStateFileTask, LoadLocalConfigurationTask, TaskContext, } from './diff.command'; @@ -15,6 +16,9 @@ import { loadBackend } from './utils'; type SyncOption = BackendOptions & { file: Array; lint: boolean; + + // experimental feature + remoteStateFile: string; }; export const SyncCommand = new BackendCommand( @@ -76,12 +80,14 @@ export const SyncCommand = new BackendCommand( opts.excludeResourceType, ), opts.lint ? LintTask() : { task: () => undefined }, - LoadRemoteConfigurationTask({ - backend, - labelSelector: opts.labelSelector, - includeResourceType: opts.includeResourceType, - excludeResourceType: opts.excludeResourceType, - }), + !opts.remoteStateFile + ? LoadRemoteConfigurationTask({ + backend, + labelSelector: opts.labelSelector, + includeResourceType: opts.includeResourceType, + excludeResourceType: opts.excludeResourceType, + }) + : ExperimentalRemoteStateFileTask(opts.remoteStateFile), DiffResourceTask(false, false), { title: 'Sync configuration',