Skip to content

rpk: Add new Schema Registry option to Shadow Link command space - #30860

Merged
r-vasquez merged 7 commits into
redpanda-data:devfrom
r-vasquez:sr-sl-new-opts
Jun 23, 2026
Merged

rpk: Add new Schema Registry option to Shadow Link command space#30860
r-vasquez merged 7 commits into
redpanda-data:devfrom
r-vasquez:sr-sl-new-opts

Conversation

@r-vasquez

@r-vasquez r-vasquez commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

This PR adds support for the new Schema Registry option in shadow link: shadow_schema_registry_api

The template

The new option is defined in Core's proto: https://github.com/redpanda-data/redpanda/blob/dev/proto/redpanda/core/admin/v2/shadow_link.proto#L418 but here is how it will look like in our config file (a 1:1)

schema_registry_sync_options:
  shadow_schema_registry_api:
    # The source Schema Registry URL to use.
    source_url: ""
    # Authentication settings for requests to the source Schema Registry.
    # If unset, requests are sent without authentication.
    auth_options:
      # Authenticate source Schema Registry requests with HTTP Basic auth.
      basic:
        # HTTP Basic auth username. For Confluent Cloud, this is the API key.
        username: ""
        # HTTP Basic auth password. For Confluent Cloud, this is the API secret.
        password: ""
    # TLS settings for requests to the source Schema Registry.
    tls_settings:
      # Whether or not TLS is enabled
      enabled: false
      # Certificates and keys are provided as files
      tls_file_settings:
        # Path to the CA
        ca_path: ""
        # Key and Cert are optional but if one is provided, then both must be
        # Path to the key
        key_path: ""
        # Path to the cert
        cert_path: ""
      # Certificates and keys are provided in PEM format
      tls_pem_settings:
        # The CA
        ca: ""
        # Key and Cert are optional but if one is provided, then both must be
        # The key
        key: ""
        # The cert
        cert: ""
      # If true, the SNI hostname will not be provided when TLS is used
      do_not_set_sni_hostname: false
    # Interval between incremental polls for new source subjects and
    # subject versions. If unset or zero, the cluster default of 10s is
    # used.
    tail_interval: 30s # duration (e.g., 30s, 1m, 1h)
    # Interval between full scans of the selected source subjects. If unset
    # or zero, the cluster default of 5m is used.
    full_sync_interval: 30s # duration (e.g., 30s, 1m, 1h)
    # Maximum request rate, in requests per second, for calls to the source
    # Schema Registry. If unset or zero, a default rate limit of 30
    # requests/s is used.
    max_source_requests_per_second: 0
    # Filter for specific Schema Registry contexts and subjects to select
    # for replication. If unset or empty, the whole source Schema Registry
    # is replicated.
    source_filter:
      # Source contexts to replicate in full, for example ".", ".prod", or
      # ".staging". If both `contexts` and `subjects` are set, the effective
      # source scope is the union of both selections.
      contexts: []
      # Exact source subjects to replicate, using Schema Registry qualified
      # subject syntax. For example, "orders-value" selects the subject in the
      # default context, and ":.prod:orders-value" selects the subject in context
      # ".prod". If both `contexts` and `subjects` are set, the union of both
      # selections is replicated. If a subject is also included by `contexts`, it
      # is counted and replicated once.
      subjects: []
    # Mapping from source contexts implied by `source_filter` to
    # destination contexts. Each source context included in the replication
    # must map to a distinct destination context to avoid
    # collisions. If unset, source context names are preserved.
    destination:
      # Preserve source context names in the destination Schema Registry.
      identity:                                                                             # Map selected source contexts to explicit destination contexts.
      exact:
        # Explicit source-to-destination context mappings. Every source context in
        # the effective source scope must have exactly one mapping.
        mappings:
          # Source context name.
          source: ""
          # Destination context name.
          destination: ""
    # Policy for handling source schema features unsupported by the
    # destination, such as rulesets or metadata tags. If unset, FAIL is
    # used.                                                                               
    unsupported_schema_feature_policy: FAIL # Fail the sync when an unsupported schema feature is encountered.

This PR also handle the whole command life cycle: create, describe and status

Describe

$ rpk shadow describe shadow-link-with-new-opts -y
SCHEMA REGISTRY SYNC
====================
SHADOWING MODE                     shadow schema registry api
SOURCE URL                         https://schema-registry-5dc240c4.d8qpb2a0pa8fqqs9ttl0.fmc.prd.cloud.redpanda.com:30081
TAIL INTERVAL                      35s
FULL SYNC INTERVAL                 35s
MAX SOURCE REQUESTS PER SECOND     30
UNSUPPORTED SCHEMA FEATURE POLICY  FAIL

BASIC AUTH:
-----------
USERNAME                           foo
PASSWORD SET AT                    2026-06-19T22:30:04Z
DESTINATION                        identity

Status

$ rpk shadow status shadow-link-with-new-opts -y
SCHEMA REGISTRY
===============
SELECTED SOURCE SUBJECTS          0
SELECTED SOURCE SUBJECT VERSIONS  0
DESTINATION SUBJECTS              0
DESTINATION SUBJECT VERSIONS      0

CURRENT SYNC:
-------------
Sync has not started.

LAST FULL SYNC:
---------------
Sync has not started.

TOTALS SINCE TASK START:
------------------------
Sync has not started.

Backports Required

  • none - not a bug fix
  • none - this is a backport
  • none - issue does not exist in previous branches
  • none - papercut/not impactful enough to backport
  • v26.1.x
  • v25.3.x
  • v25.2.x

Release Notes

Features

  • rpk shadow: support new Schema Registry Sync option shadow_schema_registry_api in Shadow Links.

The core admin/v2 proto turned
SchemaRegistrySyncOptions into a oneof and added a
shadow_schema_registry_api mode that replicates a
source Schema Registry over its HTTP API.

Add the local types with JSON tags matching the
proto field names, which the drift check and the
update field-mask paths both rely on.
Wire the new oneof branch and its nested auth, TLS,
filter, destination, and policy messages.

Intervals are only set when positive so unset
values fall back to server defaults. Output-only
fields (effective_* and password_set*) are never
sent. The cloud control plane reuses the same
adminv2 sync option types, so cloud requests get
the new mode through the same function.
Add the reverse oneof branch and helpers for its
auth, TLS, filter, destination, and policy fields.

TLS is decoded only when present so a link without
it round-trips to a nil setting rather than an
empty struct. The policy enum maps UNSPECIFIED to
the empty string, mirroring the forward direction
so the default survives a round-trip.
@r-vasquez
r-vasquez force-pushed the sr-sl-new-opts branch 2 times, most recently from 3904b4f to 375c0c4 Compare June 19, 2026 22:55
@r-vasquez
r-vasquez marked this pull request as ready for review June 20, 2026 00:04
@r-vasquez
r-vasquez requested review from a team and kbatuigas as code owners June 20, 2026 00:04
@r-vasquez
r-vasquez requested review from Copilot and weeco and removed request for a team June 20, 2026 00:04

Copilot AI 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.

Pull request overview

This PR extends rpk shadow to support the new Shadow Link Schema Registry sync mode shadow_schema_registry_api, aligning rpk’s config/types/mappers and CLI output with the updated Core Admin v2 proto.

Changes:

  • Add config/types + (un)marshal coverage for schema_registry_sync_options.shadow_schema_registry_api, including auth/TLS/filter/destination/policy fields.
  • Extend mapping logic (config ⇄ adminv2 proto) and diffing to handle the new oneof branch and related fields.
  • Add describe/status CLI rendering for schema registry API config and schema registry sync status, plus tests and proto dependency bumps.

Reviewed changes

Copilot reviewed 14 out of 16 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/go/rpk/pkg/cli/shadow/update.go Redact password placeholders for SCRAM and schema registry basic auth during update editing.
src/go/rpk/pkg/cli/shadow/update_test.go Add diffing tests for schema registry API fields / mode switches.
src/go/rpk/pkg/cli/shadow/types.go Introduce schema registry API mode config types (auth/TLS/filter/destination/policy).
src/go/rpk/pkg/cli/shadow/types_test.go Add YAML/JSON unmarshal tests for schema registry API mode; drift ignore updates.
src/go/rpk/pkg/cli/shadow/status.go Add schema registry sync status view + printing and adminv2 conversion.
src/go/rpk/pkg/cli/shadow/status_test.go Verify adminv2 → view conversion for schema registry sync status.
src/go/rpk/pkg/cli/shadow/mapper.go Map schema registry API mode between config and adminv2 proto; add enum mapping.
src/go/rpk/pkg/cli/shadow/mapper_test.go Add mapper and round-trip tests for schema registry API mode and policies.
src/go/rpk/pkg/cli/shadow/describe.go Print schema registry API mode details in describe output; add TLS helper and formatting.
src/go/rpk/pkg/cli/shadow/create.go Validate schema registry API oneof constraints; extend cloud secret validation to SR API fields.
src/go/rpk/pkg/cli/shadow/create_test.go Add validation coverage for schema registry mode/TLS/destination and cloud secret rules.
src/go/rpk/pkg/cli/shadow/BUILD Include new status tests and timestamppb dependency.
src/go/rpk/go.mod Bump core protocolbuffers dependency to pick up new schema registry fields.
src/go/rpk/go.sum Update sums for the bumped core protocolbuffers dependency.
src/go/rpk/gen/protocomments/admin/v2/comments.pb.go Regenerated comments map for new schema registry API/status/policy proto fields.
buf.gen.yaml Update buf module reference for regenerated core protos.
Files not reviewed (1)
  • src/go/rpk/gen/protocomments/admin/v2/comments.pb.go: Generated file

Comment thread src/go/rpk/pkg/cli/shadow/update.go
Comment thread src/go/rpk/pkg/cli/shadow/describe.go
Comment thread src/go/rpk/pkg/cli/shadow/describe.go
Comment thread src/go/rpk/pkg/cli/shadow/describe.go
@vbotbuildovich

vbotbuildovich commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

CI test results

test results on build#86062
test_status test_class test_method test_arguments test_kind job_url passed reason test_history
FLAKY(PASS) ShadowLinkTopicFailoverTests test_producer_ids_failover {"storage_mode": "local"} integration https://buildkite.com/redpanda/redpanda/builds/86062#019ee260-2555-482e-a849-a175bdba7810 10/11 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0033, p0=1.0000, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.3487, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ShadowLinkTopicFailoverTests&test_method=test_producer_ids_failover
FLAKY(PASS) ShadowLinkingReplicationTests test_auto_prefix_trimming {"source_cluster_spec": {"cluster_type": "redpanda"}, "storage_mode": "tiered_cloud", "with_failures": true} integration https://buildkite.com/redpanda/redpanda/builds/86062#019ee260-2557-4bd6-9939-ed474739ce99 37/41 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0369, p0=0.1830, reject_threshold=0.0100. adj_baseline=0.1068, p1=0.3693, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ShadowLinkingReplicationTests&test_method=test_auto_prefix_trimming
test results on build#86106
test_status test_class test_method test_arguments test_kind job_url passed reason test_history
FLAKY(PASS) NodeWiseRecoveryTest test_recovery_local_data_missing {"wait_for_final_manifest_uploads": false} integration https://buildkite.com/redpanda/redpanda/builds/86106#019ef0b5-17f7-410f-a112-4318492698cb 18/21 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0492, p0=0.2580, reject_threshold=0.0100. adj_baseline=0.1404, p1=0.4529, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=NodeWiseRecoveryTest&test_method=test_recovery_local_data_missing
test results on build#86113
test_status test_class test_method test_arguments test_kind job_url passed reason test_history
FLAKY(FAIL) ShadowLinkingReplicationTests test_auto_prefix_trimming {"source_cluster_spec": {"cluster_type": "redpanda"}, "storage_mode": "tiered", "with_failures": false} integration https://buildkite.com/redpanda/redpanda/builds/86113#019ef175-67d9-4777-a5bf-8b587b118728 16/21 Test FAILS after retries.Significant increase in flaky rate(baseline=0.0378, p0=0.0061, reject_threshold=0.0100) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ShadowLinkingReplicationTests&test_method=test_auto_prefix_trimming
FLAKY(PASS) NodeWiseRecoveryTest test_recovery_local_data_missing {"wait_for_final_manifest_uploads": true} integration https://buildkite.com/redpanda/redpanda/builds/86113#019ef175-67d6-4de2-a78a-555030ff093c 10/11 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0490, p0=1.0000, reject_threshold=0.0100. adj_baseline=0.1400, p1=0.2213, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=NodeWiseRecoveryTest&test_method=test_recovery_local_data_missing

Mateoc
Mateoc previously approved these changes Jun 22, 2026
Comment thread src/go/rpk/pkg/cli/shadow/create.go Outdated
Comment thread src/go/rpk/pkg/cli/shadow/create.go Outdated
Creating or updating a shadow link did not check
the new shadow_schema_registry_api mode, so a
config that set both shadowing modes, both
destination mappings, or plain cloud secrets was
sent straight to the server. Add client-side
validation mirroring the existing client-option
rules, and redact the basic-auth password in the
update editor the way the SCRAM password already
is.

validateParsedShadowLinkConfig now binds the
client options once and nil-guards every access,
since a cloud config may omit client_options
entirely; previously such a config panicked. The
cloud secret checks no longer return early when
client options are absent, so the schema registry
secrets are still validated, and the four plain
secret checks collapse into one loop over all
secret-bearing fields. File-based TLS is rejected
for the schema registry API under cloud options
too, since the agent cannot read local paths.
Render the new SR fields in both the text and the
JSON/YAML output, reusing the reverse mappers and
showing effective interval and rate values plus
auth metadata without the password.

The client TLS printing is extracted into a shared
helper since the schema registry API carries the
same core TLS settings. The schema registry
section was also added to the cloud section
header map.
The admin status now carries a schema registry
sync status, so surface its inventory counts,
the running sync, the last full sync, cumulative
totals, and the last error.

A new print-registry flag selects the section, and
it joins the default set. The dataplane API does
not expose this status, so it is populated only on
the self-hosted path; cloud output omits it for now.
We allow empty client options in Cloud configs as
you just need the Redpanda ID. However, this print
here could cause a panic.

In reality this was never reported as Cloud always
require ClientOpts.TLS.Enabled to be true and it
was provided in the config template.
@vbotbuildovich

Copy link
Copy Markdown
Collaborator

Retry command for Build#86113

please wait until all jobs are finished before running the slash command

/ci-repeat 1
skip-redpanda-build
skip-units
skip-rebase
tests/rptest/tests/cluster_linking_e2e_test.py::ShadowLinkingReplicationTests.test_auto_prefix_trimming@{"source_cluster_spec":{"cluster_type":"redpanda"},"storage_mode":"tiered","with_failures":false}

@r-vasquez

Copy link
Copy Markdown
Contributor Author

/ci-repeat 1
skip-redpanda-build
skip-units
skip-rebase
tests/rptest/tests/cluster_linking_e2e_test.py::ShadowLinkingReplicationTests.test_auto_prefix_trimming@{"source_cluster_spec":{"cluster_type":"redpanda"},"storage_mode":"tiered","with_failures":false}

@r-vasquez
r-vasquez merged commit 886067c into redpanda-data:dev Jun 23, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants