Skip to content

Migrate to DefineConfigurationV2 / RunConnector (prerequisite for CE-1183) - #33

Open
laurenleach wants to merge 3 commits into
mainfrom
lauren/migrate-to-configuration-v2
Open

Migrate to DefineConfigurationV2 / RunConnector (prerequisite for CE-1183)#33
laurenleach wants to merge 3 commits into
mainfrom
lauren/migrate-to-configuration-v2

Conversation

@laurenleach

Copy link
Copy Markdown

Prerequisite for CE-1183. Plumbing only — this PR deliberately contains no guard logic.

baton-metabase was still on the V1 entrypoint, so *cli.ConnectorOpts never reached connector.New. That is precisely what blocks reading the sync resource-type filter, so the migration is split out on its own to keep the guard diff reviewable.

What changed

Area V1 → V2
cmd/baton-metabase DefineConfiguration + getConnector + cmd.Execute()config.RunConnector
pkg/config ConfigConfiguration; regenerated conf.gen.go
connector.New now takes *cli.ConnectorOpts, returns (ConnectorBuilderV2, []connectorbuilder.Opt, error)
ResourceSyncers []connectorbuilder.ResourceSyncer[]connectorbuilder.ResourceSyncerV2
userBuilder, groupBuilder *pagination.TokenresourceSdk.SyncOpAttrs; (…, string, annotations.Annotations, error)(…, *SyncOpResults, error)

Grant/Revoke are untouched — V2 only changes the three sync methods.

Notes for review

  • opts is accepted but deliberately unread. Wiring it into the builders is the CE-1183 follow-up; adding it here would be the guard change this PR is meant to exclude.
  • field.Validate moved into New from the deleted getConnector, so config validation is not silently lost.
  • RunConnector gets WithProvisioningEnabled() (this connector implements Grant/Revoke) and WithDefaultCapabilitiesConnectorBuilderV2(&connector.Connector{}), so a zero-value Connector{} serves the capability set.
  • WithConstraints(FieldRelationships...) is now actually passed — FieldRelationships was declared but never wired in under V1.
  • The conf.gen.go GetString change is the current generator's output for the pinned SDK (it now also accepts []byte), not a hand edit.

Verification

  • baton_capabilities.json and config_schema.json regenerate byte-identical — the strongest available signal that this is pure plumbing with no behaviour change.
  • go build, go vet, go test ./... all pass.
  • golangci-lint reports the same 8 pre-existing staticcheck issues as main (deprecated trait and actions APIs, called out in CE-1183) and adds none.

Unblocks CE-1183, and in turn CE-1209 (baton-metabase-v049 vendors this connector).

🤖 Generated with Claude Code

Prerequisite plumbing only — no guard logic, no behaviour change.

This connector was still on the V1 entrypoint, which means *cli.ConnectorOpts
never reaches connector.New. That is what blocks reading the sync resource-type
filter (CE-1183), so the migration is split out here on its own.

- cmd: config.DefineConfiguration + getConnector + cmd.Execute() ->
  config.RunConnector, with WithProvisioningEnabled (this connector implements
  Grant/Revoke) and WithDefaultCapabilitiesConnectorBuilderV2 so a zero-value
  Connector{} serves the capability set.
- pkg/config: `Config` -> `Configuration`, adding the WithConstraints wiring
  that FieldRelationships already declared but never passed. Regenerated
  conf.gen.go; the GetString change is the current generator's output for the
  pinned SDK, which also accepts []byte.
- connector.New: now returns (connectorbuilder.ConnectorBuilderV2,
  []connectorbuilder.Opt, error) and takes *cli.ConnectorOpts. The opts
  parameter is accepted but deliberately unread — wiring it up is the follow-up.
  field.Validate moved in from the deleted getConnector so validation is not
  lost.
- ResourceSyncers returns []connectorbuilder.ResourceSyncerV2, and both builders
  move to the V2 sync signatures: *pagination.Token -> resourceSdk.SyncOpAttrs,
  and (…, string, annotations.Annotations, error) -> (…, *SyncOpResults, error).
  Grant/Revoke are unchanged; V2 only alters the three sync methods.
- Tests updated for the new signatures.

baton_capabilities.json and config_schema.json regenerate byte-identical, which
is the check that this is pure plumbing. golangci-lint reports the same 8
pre-existing staticcheck issues as main (the deprecated trait/actions APIs) and
no new ones.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@laurenleach laurenleach self-assigned this Aug 14, 2026
@linear-code

linear-code Bot commented Aug 14, 2026

Copy link
Copy Markdown

CE-1183

Comment thread pkg/connector/users.go
opts, err := getPageOptions(&attrs.PageToken, client.ItemsPerPage)
if err != nil {
return nil, "", nil, err
return nil, nil, err

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Suggestion: This is the only path in List that returns a nil *SyncOpResults; every other return builds one (&SyncOpResults{Annotations: ann}). The SDK nil-guards this (resource_syncer.go sets retOptions = &SyncOpResults{}), so it is not a runtime panic, but the new tests dereference the results value unconditionally (e.g. syncResults.NextPageToken in users_test.go:38), so a test covering an invalid page token would panic here. Returning &resourceSdk.SyncOpResults{} keeps the contract uniform.

Comment thread pkg/connector/connector.go Outdated
func New(ctx context.Context, config *cfg.Metabase, _ *cli.ConnectorOpts) (connectorbuilder.ConnectorBuilderV2, []connectorbuilder.Opt, error) {
l := ctxzap.Extract(ctx)

if err := field.Validate(cfg.Configuration, config); err != nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Suggestion: RunConnector already validates the config before it calls Newpkg/cli/commands.go runs field.Validate(confschema, t, field.WithAuthMethod(v.GetString("auth-method"))) on every path (run, server, capabilities). This call repeats that check but omits field.WithAuthMethod, so if auth methods are ever added to Configuration this copy would reject configs the SDK accepted. Harmless today (no auth methods, FieldRelationships is empty); consider dropping it or passing the auth method through from opts.SelectedAuthMethod.

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Connector PR Review: Migrate to DefineConfigurationV2 / RunConnector (prerequisite for CE-1183)

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base a11986b7fcd5.
Review mode: incremental since 959d000
View review run

Review Summary

The only new commit (b933fc5) drops connectorrunner.WithProvisioningEnabled() from cmd/baton-metabase/main.go. I verified this against baton-sdk v0.24.1: the V1 entrypoint on main passed no runner options either, and provisioning in service mode is driven by BATON_PROVISIONING and the on-demand grant/revoke flags in cli.MakeMainCommand, not by this option, so the removal restores V1 parity rather than disabling provisioning, and CAPABILITY_PROVISION still comes from the registered ResourceProvisionerV2 in GetCapabilities. The full PR diff was re-scanned for security and correctness; no new issues found. The prior pkg/connector/users.go:28 finding is still open and is carried forward below.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • pkg/connector/users.go:28 - carried over from the previous review, still open: the getPageOptions error path is the only List return with a nil *SyncOpResults, unlike every other return in the file. Confirmed non-fatal in production, since builder.ListResources substitutes an empty SyncOpResults when the connector returns nil, so this is a consistency and test-fragility issue, not a crash.
  • PR description - two statements no longer match the code. It says RunConnector gets WithProvisioningEnabled(), which b933fc5 removed, and that field.Validate moved into New, which it did not: connector.New does not call field.Validate. Validation is not lost, since the SDK calls it in cli.MakeMainCommand, MakeGRPCServerCommand, and the lambda command, but the description would send a reader looking for it in New.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `pkg/connector/users.go`:
- Around line 26-29: the getPageOptions error path returns nil for the *resourceSdk.SyncOpResults return value, making it the only return in this file with a nil results pointer. Every other return (lines 38, 45, 50) returns a non-nil struct. This is not a production crash, because builder.ListResources in baton-sdk substitutes an empty SyncOpResults when the connector returns nil, but it leaves the function inconsistent and means any future test that reads syncResults.NextPageToken on this path will panic. Return a pointer to an empty resourceSdk.SyncOpResults value instead of nil, matching the rest of the file.

In the PR description (no code change required):
- Update two stale claims. First, it states that RunConnector gets WithProvisioningEnabled(), but commit b933fc5 removed that call, correctly, since the V1 entrypoint on main passed no runner options and provisioning is driven by BATON_PROVISIONING and the on-demand grant/revoke flags in cli.MakeMainCommand. Second, it states that field.Validate moved into New, but connector.New in pkg/connector/connector.go does not call field.Validate. Validation still happens, because the SDK calls it in cli.MakeMainCommand, so reword the description to say the SDK owns config validation under the V2 entrypoint rather than implying it lives in New.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No blocking issues found.

Review feedback: baton-sdk already validates the configuration as part of
RunConnector, so calling field.Validate inside New duplicates it. The call was
carried over from the deleted V1 getConnector, where it was the connector's own
responsibility; under V2 it is not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No blocking issues found.

Review feedback. The V1 DefineConfiguration call passed no connectorrunner
options at all, so adding WithProvisioningEnabled() here would have flipped
provisioning on unconditionally (it sets cfg.provisioningEnabled = true) rather
than leaving it under whatever gates it before. That is a behaviour change, and
this PR is meant to be pure entrypoint plumbing.

Implementing Grant/Revoke/CreateAccount is not the same thing as the runner
being told to enable provisioning, which is the mistake behind the original
change. WithDefaultCapabilitiesConnectorBuilderV2 stays: that is what lets
`capabilities` run without credentials.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No blocking issues found.

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