Skip to content

feat: validate conf libraries contain spock#411

Merged
GabriellePoncey merged 4 commits into
mainfrom
chore/PLAT-171/validate-conf-spock
Jun 25, 2026
Merged

feat: validate conf libraries contain spock#411
GabriellePoncey merged 4 commits into
mainfrom
chore/PLAT-171/validate-conf-spock

Conversation

@GabriellePoncey

@GabriellePoncey GabriellePoncey commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Prevent users from disabling the spock extension via postgresql_conf.shared_preload_libraries. The control plane has a hard dependency on spock, so removing it would silently break replication.

Changes

  • Add validateConfLibraries to reject any postgresql_conf that explicitly sets shared_preload_libraries without including spock

  • Wire into validateDatabaseSpec (spec-level conf) and validateNode (node-level conf) for the create path

  • Wire into validateDatabaseUpdate for the update path, at both spec and node level

Testing

  • TestValidateConfLibraries: unit tests covering absent key, valid configs, uppercase param name, and missing spock

  • Invalid postgresql_conf cases added to TestValidateDatabaseSpec and TestValidateNode to confirm the check is called in the right places

  • TestValidateDatabaseUpdate_LibraryConf: confirms the check runs on update requests at both spec and node level

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

A new helper validateConfLibraries is added to validate.go to check that spock appears in the shared_preload_libraries GUC value when the key is present. This helper is then called in validateDatabaseSpec, validateNode, and validateDatabaseUpdate, enforcing the requirement across database-spec, per-node, and update-path validation. Comprehensive test coverage includes direct unit tests for the helper and integration tests extending existing validator test tables.

Changes

spock Library Validation

Layer / File(s) Summary
validateConfLibraries helper
server/internal/api/apiv1/validate.go
Adds validateConfLibraries, which reads shared_preload_libraries from a postgresql_conf map, splits it by comma, and returns a validation error if spock is not among the entries; returns nil when the key is absent.
Integration into spec, node, and update validators
server/internal/api/apiv1/validate.go
Calls validateConfLibraries on spec.PostgresqlConf inside validateDatabaseSpec, on node.PostgresqlConf inside validateNode, and on both database-level and per-node PostgresqlConf inside validateDatabaseUpdate, so all three validation paths now enforce the spock requirement.
Test coverage for validator and integrations
server/internal/api/apiv1/validate_test.go
Adds TestValidateConfLibraries to directly test the helper with valid and invalid configurations, TestValidateDatabaseUpdate_LibraryConf to test the update path, and extends TestValidateNode and TestValidateDatabaseSpec with "invalid lib conf" cases that verify missing spock is rejected at both levels.

Poem

A rabbit checks the libraries list,
No spock? That config gets dismissed!
Database spec, node, and update too,
All paths must include it through.
Hop along, all GUCs in line! 🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding validation to ensure postgresql_conf libraries contain the spock extension.
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.
Description check ✅ Passed The PR description includes the required Summary, Changes, and Testing sections and clearly explains the validation behavior.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/PLAT-171/validate-conf-spock

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.

Actionable comments posted: 2

🤖 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.

Inline comments:
In `@server/internal/api/apiv1/validate.go`:
- Line 302: The validateConfLibraries call for PostgreSQL configuration
validation is using validation.NewPath("postgresql_conf") which creates a fresh
path without node context, causing validation errors to lose the node-scoped
context. Replace validation.NewPath("postgresql_conf") with
path.Append("postgresql_conf") to maintain the proper node context (nodes[i]...)
in the validation error paths when PostgreSQL configuration validation occurs at
the node level.
- Around line 45-49: The key lookup in validateConfLibraries uses case-sensitive
comparison for "shared_preload_libraries", but PostgreSQL GUC names are
case-insensitive, allowing mixed-case variants to bypass the spock safeguard.
Update the key lookup logic to handle case-insensitivity similar to how
validateAuthFileGUCs already does it, ensuring that the validation properly
catches any case variation of the shared_preload_libraries key before returning
nil defaults.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2ced2b17-b9d9-4176-9216-277eb18a17b6

📥 Commits

Reviewing files that changed from the base of the PR and between 847bb00 and f1445f7.

📒 Files selected for processing (1)
  • server/internal/api/apiv1/validate.go

Comment thread server/internal/api/apiv1/validate.go Outdated
Comment thread server/internal/api/apiv1/validate.go Outdated
@codacy-production

codacy-production Bot commented Jun 17, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 duplication

Metric Results
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@jason-lynch jason-lynch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This implementation is looking good! Could you please also add some tests for this function to server/internal/api/apiv1/validate_test.go. I'm thinking maybe:

  • Add a TestValidateConfLibraries to test this all the cases of this function individually
  • Just to validate that it's being called in the right place, add an invalid PostgresqlConf and expected error message to the invalid test cases in both TestValidateDatabaseSpec and TestValidateNode

}

func validateConfLibraries(conf map[string]any, path validation.Path) []error {
for key, val := range conf {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you please add a comment here noting that we can't do a simple lookup because parameter names are case-insensitive? Your implementation is good, and I want to make sure we don't accidentally change it in the future.

@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)
server/internal/api/apiv1/validate_test.go (2)

498-539: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the non-string shared_preload_libraries branch in helper tests.

validateConfLibraries also returns an error when shared_preload_libraries is present but not a string. Adding that case here will protect the full helper contract.

Proposed test-table addition
 func TestValidateConfLibraries(t *testing.T) {
 	for _, tc := range []struct {
 		name     string
 		conf     map[string]any
 		expected []string
 	}{
@@
 		{
+			name: "invalid conf non-string shared_preload_libraries",
+			conf: map[string]any{"shared_preload_libraries": 123},
+			expected: []string{
+				`"shared_preload_libraries" must be a string`,
+			},
+		},
+		{
 			name: "invalid conf missing spock",
 			conf: map[string]any{"shared_preload_libraries": "snowflake"},
 			expected: []string{
 				`"spock" must be included in shared_preload_libraries`,
 			},
 		},
🤖 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 `@server/internal/api/apiv1/validate_test.go` around lines 498 - 539, The
TestValidateConfLibraries test table does not cover the case where
shared_preload_libraries is present but not a string value. Add a new test case
to the table that sets shared_preload_libraries to a non-string type (such as an
integer or boolean) and include the expected error message that
validateConfLibraries returns when encountering a non-string value for this
configuration parameter. This will ensure full coverage of the
validateConfLibraries function's error handling logic.

1410-1426: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a spec-level create-path case in TestValidateDatabaseSpec.

This new case covers node-level postgresql_conf, but validateDatabaseSpec also validates spec.PostgresqlConf directly. A spec-level missing-spock case here would complete create-path coverage.

Proposed test-table addition
 		{
+			name: "invalid spec-level lib conf",
+			spec: &api.DatabaseSpec{
+				PostgresqlConf: map[string]any{"shared_preload_libraries": "snowflake"},
+				Nodes: []*api.DatabaseNodeSpec{
+					{
+						Name:    "n1",
+						HostIds: []api.Identifier{api.Identifier("host-1")},
+					},
+				},
+			},
+			expected: []string{
+				`"spock" must be included in shared_preload_libraries`,
+			},
+		},
+		{
 			name: "invalid lib conf",
 			spec: &api.DatabaseSpec{
 				Nodes: []*api.DatabaseNodeSpec{
 					{
 						Name: "n1",
🤖 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 `@server/internal/api/apiv1/validate_test.go` around lines 1410 - 1426, The
current test case at the node-level PostgresqlConf is incomplete because
validateDatabaseSpec also validates spec-level PostgresqlConf directly. Add a
new test case to the TestValidateDatabaseSpec test table with a DatabaseSpec
that has PostgresqlConf (at the spec level, not nested under Nodes) containing
shared_preload_libraries without "spock". The test case should expect the same
validation error message as the node-level case, ensuring spec-level
PostgresqlConf validation is covered in the create-path tests.
🤖 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 `@server/internal/api/apiv1/validate_test.go`:
- Around line 498-539: The TestValidateConfLibraries test table does not cover
the case where shared_preload_libraries is present but not a string value. Add a
new test case to the table that sets shared_preload_libraries to a non-string
type (such as an integer or boolean) and include the expected error message that
validateConfLibraries returns when encountering a non-string value for this
configuration parameter. This will ensure full coverage of the
validateConfLibraries function's error handling logic.
- Around line 1410-1426: The current test case at the node-level PostgresqlConf
is incomplete because validateDatabaseSpec also validates spec-level
PostgresqlConf directly. Add a new test case to the TestValidateDatabaseSpec
test table with a DatabaseSpec that has PostgresqlConf (at the spec level, not
nested under Nodes) containing shared_preload_libraries without "spock". The
test case should expect the same validation error message as the node-level
case, ensuring spec-level PostgresqlConf validation is covered in the
create-path tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 103e3110-f41b-4565-b8ab-09f4cba0c15b

📥 Commits

Reviewing files that changed from the base of the PR and between f1445f7 and 57a8a5a.

📒 Files selected for processing (2)
  • server/internal/api/apiv1/validate.go
  • server/internal/api/apiv1/validate_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/internal/api/apiv1/validate.go

@jason-lynch jason-lynch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice work!

@GabriellePoncey GabriellePoncey merged commit a60c48c into main Jun 25, 2026
3 checks passed
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.

2 participants