Skip to content

feat(config): add config command to view and set broker configuration - #33

Merged
jamestelfer merged 2 commits into
mainfrom
config-command-central-config
Jul 6, 2026
Merged

jamestelfer merged 2 commits into
mainfrom
config-command-central-config

Conversation

@jamestelfer

@jamestelfer jamestelfer commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Purpose

Operators had no supported way to discover or change the central broker configuration. The config file was never created automatically and had only a read path, so the only options were to guess its location and hand-author YAML. That is error-prone: a typo in the profile-filter regex or an invalid log level was only surfaced later, at broker startup.

This adds a first-class config command so an operator can locate the file, inspect the current values, and set or clear them safely. Values are validated before they are written, turning a class of latent startup failures into immediate, actionable feedback at the point of change.

Context

  • Config remains a host-controlled default, not a security boundary. config set writes a host path and is an operator interface, not agent-reachable; the defence is the sandbox keeping the file and launch inputs out of the agent's reach, consistent with the project threat model.
  • Known limitation: set round-trips through the schema, so hand-written YAML comments are not preserved. Accepted trade-off for a three-key config.
  • See commit history for the implementation detail.

Add `config path`, `config list`, and `config set` subcommands so
operators can locate, inspect, and modify the host-side configuration
file. Previously the file had only a read path and was never created
automatically, so operators had to author it by hand.

Extend pkg/config with a Set write path that creates the file and its
parent directory when absent, preserves other keys, clears a key on an
empty value, and validates values before writing. Share validation and
decoding between Load and Set, and keep validation errors path-free so
Set does not misleadingly reference the file for a value typed on the
CLI.

Deduplicate the CLI writer resolution shared with the doctor command.
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jamestelfer, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0b6ab429-6f05-4406-89e2-db02e4d4f537

📥 Commits

Reviewing files that changed from the base of the PR and between 22f5d4e and ca01d8c.

📒 Files selected for processing (2)
  • cmd/imds-broker/config.go
  • pkg/config/config.go
📝 Walkthrough

Walkthrough

This PR adds a config CLI command group (path, list, set) to imds-broker, backed by new pkg/config helpers: exported key constants, a Keys slice, fileSchema/validate/decodeFile functions, and a rewritten Set function. doctor.go and main.go are updated to wire in a shared writer helper and the new command, with corresponding tests added.

Changes

Config schema and CLI

Layer / File(s) Summary
Config schema, keys, and Load/Set core logic
pkg/config/config.go
Adds KeyProfileFilter, KeyRegion, KeyLogLevel constants and Keys slice; introduces fileSchema, validate, decodeFile helpers with strict YAML decoding, empty-file/multi-document handling; rewrites Load to use these helpers and Set to read-modify-validate-persist config with 0700/0600 permissions.
pkg/config Set test coverage
pkg/config/config_test.go
Adds tests for Set covering file creation, key preservation, empty-value clearing, unknown key errors, invalid value errors, malformed existing files, and round-trip via Load.
config CLI command implementation
cmd/imds-broker/config.go
Adds configCommand with path, list, set subcommands, commandWriter output helper, and valueOrUnset rendering for unset vs empty values.
CLI wiring and doctor writer refactor
cmd/imds-broker/main.go, cmd/imds-broker/doctor.go
Registers configCommand() in main's command list; doctorCommand now uses commandWriter(cmd) instead of inline writer-selection logic.
CLI config command tests
cmd/imds-broker/main_test.go
Adds runConfigCmd test harness and tests for config path, config list, config set, and argument validation.

Possibly related PRs

  • jamestelfer/imds-broker#28: Modifies the same pkg/config/config.go loader/validation logic and its CLI integration, which this PR extends with Set support.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: adding a config command to view and set broker configuration.
Description check ✅ Passed The description is directly related to the changeset and explains the new config command, validation, and config-file behavior.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
cmd/imds-broker/config.go (1)

86-88: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keys list can drift from brokerconfig.Keys.

The Description hardcodes the three key constants instead of deriving from brokerconfig.Keys (used elsewhere, e.g. in Set's unknown-key error via strings.Join(Keys, ", ")). If a key is added/removed from Keys, this usage text will silently go stale.

♻️ Suggested fix
-		Description: "Valid keys: " + brokerconfig.KeyProfileFilter + ", " +
-			brokerconfig.KeyRegion + ", " + brokerconfig.KeyLogLevel +
-			". An empty value clears the key.",
+		Description: "Valid keys: " + strings.Join(brokerconfig.Keys, ", ") +
+			". An empty value clears the key.",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/imds-broker/config.go` around lines 86 - 88, The usage text in the config
description is hardcoding individual brokerconfig key constants, which can drift
from the canonical brokerconfig.Keys list used elsewhere. Update the Description
construction in the config setup to derive the “Valid keys” text from
brokerconfig.Keys (for example by joining the list) so it stays automatically in
sync whenever keys change.
pkg/config/config.go (1)

192-201: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Consider an atomic write (temp file + rename) to protect operator config.

os.WriteFile truncates then writes in place, so an interrupted or failed write can leave a partially written or empty config file—losing the very keys Set works to preserve. Writing to a temp file in the same directory and os.Rename-ing into place makes the update atomic and avoids clobbering existing content on failure.

♻️ Suggested atomic write
 	if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
 		return nil, fmt.Errorf("create config dir: %w", err)
 	}
-	if err := os.WriteFile(path, data, 0o600); err != nil {
-		return nil, fmt.Errorf("write config %q: %w", path, err)
+	tmp, err := os.CreateTemp(filepath.Dir(path), ".config-*.yaml.tmp")
+	if err != nil {
+		return nil, fmt.Errorf("create temp config: %w", err)
+	}
+	tmpName := tmp.Name()
+	defer os.Remove(tmpName) // no-op after a successful rename
+	if err := tmp.Chmod(0o600); err != nil {
+		tmp.Close()
+		return nil, fmt.Errorf("chmod temp config: %w", err)
+	}
+	if _, err := tmp.Write(data); err != nil {
+		tmp.Close()
+		return nil, fmt.Errorf("write temp config: %w", err)
+	}
+	if err := tmp.Close(); err != nil {
+		return nil, fmt.Errorf("close temp config: %w", err)
+	}
+	if err := os.Rename(tmpName, path); err != nil {
+		return nil, fmt.Errorf("write config %q: %w", path, err)
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/config/config.go` around lines 192 - 201, The config persistence path in
Set currently uses os.WriteFile, which can leave a truncated or empty file if
the write is interrupted. Update the write flow to use an atomic temp-file write
in the same directory followed by os.Rename so the existing config is only
replaced on success. Keep the existing error handling around yaml.Marshal and
os.MkdirAll, and adjust the final write step in pkg/config/config.go to use a
temp file plus rename sequence.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@cmd/imds-broker/config.go`:
- Around line 86-88: The usage text in the config description is hardcoding
individual brokerconfig key constants, which can drift from the canonical
brokerconfig.Keys list used elsewhere. Update the Description construction in
the config setup to derive the “Valid keys” text from brokerconfig.Keys (for
example by joining the list) so it stays automatically in sync whenever keys
change.

In `@pkg/config/config.go`:
- Around line 192-201: The config persistence path in Set currently uses
os.WriteFile, which can leave a truncated or empty file if the write is
interrupted. Update the write flow to use an atomic temp-file write in the same
directory followed by os.Rename so the existing config is only replaced on
success. Keep the existing error handling around yaml.Marshal and os.MkdirAll,
and adjust the final write step in pkg/config/config.go to use a temp file plus
rename sequence.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0e6dac31-036d-4ddb-a45a-a1cb261b3278

📥 Commits

Reviewing files that changed from the base of the PR and between 5cc8f21 and 22f5d4e.

📒 Files selected for processing (6)
  • cmd/imds-broker/config.go
  • cmd/imds-broker/doctor.go
  • cmd/imds-broker/main.go
  • cmd/imds-broker/main_test.go
  • pkg/config/config.go
  • pkg/config/config_test.go

@jamestelfer jamestelfer changed the title Add config command to view and set broker configuration feat(config): add config command to view and set broker configuration Jul 6, 2026
Build the `config set` valid-keys usage text from brokerconfig.Keys so it
cannot drift from the canonical list.

Replace the direct os.WriteFile in Set with a temp-file write plus rename
so an interrupted write cannot truncate the operator's existing config.
@jamestelfer
jamestelfer merged commit 8b4c39c into main Jul 6, 2026
4 checks passed
@jamestelfer
jamestelfer deleted the config-command-central-config branch July 6, 2026 07:00
@octo-sts octo-sts Bot mentioned this pull request Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant