From d4504d85c303ef9a280d12783fc8e4dbe26a5c6e Mon Sep 17 00:00:00 2001 From: Devin Wong Date: Tue, 14 Apr 2026 16:40:18 -0700 Subject: [PATCH 1/2] feat: add support for --help and version commands in aks-node-controller --- aks-node-controller/app.go | 36 +++++++++++++++++++++++++++------ aks-node-controller/app_test.go | 12 +++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/aks-node-controller/app.go b/aks-node-controller/app.go index d82adbafbc1..ad015aec8ec 100644 --- a/aks-node-controller/app.go +++ b/aks-node-controller/app.go @@ -97,6 +97,10 @@ type ProvisionStatusFiles struct { } func (a *App) Run(ctx context.Context, args []string) int { + if handled, exitCode := handleInfoCommand(args); handled { + return exitCode + } + slog.Info("aks-node-controller started", "args", args) err := a.run(ctx, args) exitCode := errToExitCode(err) @@ -108,6 +112,32 @@ func (a *App) Run(ctx context.Context, args []string) int { return exitCode } +// handleInfoCommand handles --version, version, --help, and help commands +// without logging noise. Returns (true, exitCode) if handled. +func handleInfoCommand(args []string) (bool, int) { + if len(args) < 2 { + return false, 0 + } + switch args[1] { + case "--version", "version": + //nolint:forbidigo // stdout is part of the interface + fmt.Println(Version) + return true, 0 + case "--help", "help": + //nolint:forbidigo // stdout is part of the interface + fmt.Println("Usage: aks-node-controller [options]") + fmt.Println() + fmt.Println("Commands:") + fmt.Println(" provision Run node provisioning") + fmt.Println(" provision-wait Wait for provisioning to complete") + fmt.Println(" version Print the version") + fmt.Println(" help Print this help message") + return true, 0 + default: + return false, 0 + } +} + func (a *App) run(ctx context.Context, args []string) error { command := "" if len(args) >= 2 { @@ -117,12 +147,6 @@ func (a *App) run(ctx context.Context, args []string) error { return errors.New("missing command argument") } - if command == "--version" || command == "version" { - //nolint:forbidigo // stdout is part of the interface - fmt.Println(Version) - return nil - } - cmd, ok := getCommandRegistry()[command] if !ok { return fmt.Errorf("unknown command: %s", command) diff --git a/aks-node-controller/app_test.go b/aks-node-controller/app_test.go index dc80b711bc7..6915bd3356e 100644 --- a/aks-node-controller/app_test.go +++ b/aks-node-controller/app_test.go @@ -78,6 +78,18 @@ func TestApp_Run(t *testing.T) { assert.Equal(t, 0, exitCode) }) + t.Run("--help flag returns success exit code", func(t *testing.T) { + tt := NewTestApp(t, TestAppConfig{}) + exitCode := tt.App.Run(context.Background(), []string{"aks-node-controller", "--help"}) + assert.Equal(t, 0, exitCode) + }) + + t.Run("help command returns success exit code", func(t *testing.T) { + tt := NewTestApp(t, TestAppConfig{}) + exitCode := tt.App.Run(context.Background(), []string{"aks-node-controller", "help"}) + assert.Equal(t, 0, exitCode) + }) + t.Run("provision command with missing flag", func(t *testing.T) { tt := NewTestApp(t, TestAppConfig{}) exitCode := tt.App.Run(context.Background(), []string{"aks-node-controller", "provision"}) From 4a081f5dd8074f04696e2b35a9723fbacb4a76e1 Mon Sep 17 00:00:00 2001 From: Devin Wong Date: Tue, 14 Apr 2026 18:36:55 -0700 Subject: [PATCH 2/2] refactor: simplify handleInfoCommand and update return values --- aks-node-controller/app.go | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/aks-node-controller/app.go b/aks-node-controller/app.go index ad015aec8ec..781ea0358a5 100644 --- a/aks-node-controller/app.go +++ b/aks-node-controller/app.go @@ -97,8 +97,8 @@ type ProvisionStatusFiles struct { } func (a *App) Run(ctx context.Context, args []string) int { - if handled, exitCode := handleInfoCommand(args); handled { - return exitCode + if handled := handleInfoCommand(args); handled { + return 0 } slog.Info("aks-node-controller started", "args", args) @@ -113,28 +113,26 @@ func (a *App) Run(ctx context.Context, args []string) int { } // handleInfoCommand handles --version, version, --help, and help commands -// without logging noise. Returns (true, exitCode) if handled. -func handleInfoCommand(args []string) (bool, int) { +// without logging noise. Returns true if handled. +func handleInfoCommand(args []string) bool { if len(args) < 2 { - return false, 0 + return false } switch args[1] { case "--version", "version": - //nolint:forbidigo // stdout is part of the interface - fmt.Println(Version) - return true, 0 + _, _ = fmt.Fprintln(os.Stdout, Version) + return true case "--help", "help": - //nolint:forbidigo // stdout is part of the interface - fmt.Println("Usage: aks-node-controller [options]") - fmt.Println() - fmt.Println("Commands:") - fmt.Println(" provision Run node provisioning") - fmt.Println(" provision-wait Wait for provisioning to complete") - fmt.Println(" version Print the version") - fmt.Println(" help Print this help message") - return true, 0 + _, _ = fmt.Fprintln(os.Stdout, "Usage: aks-node-controller [options]") + _, _ = fmt.Fprintln(os.Stdout) + _, _ = fmt.Fprintln(os.Stdout, "Commands:") + _, _ = fmt.Fprintln(os.Stdout, " provision Run node provisioning") + _, _ = fmt.Fprintln(os.Stdout, " provision-wait Wait for provisioning to complete") + _, _ = fmt.Fprintln(os.Stdout, " version Print the version") + _, _ = fmt.Fprintln(os.Stdout, " help Print this help message") + return true default: - return false, 0 + return false } }