Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ require (
github.com/redpanda-data/common-go/api v0.0.0-20251118002524-720a3c2f5569
github.com/redpanda-data/common-go/net v0.1.1-0.20240429123545-4da3d2b371f7
github.com/redpanda-data/common-go/rpadmin v0.2.0
github.com/redpanda-data/common-go/rpsr v0.1.2
github.com/redpanda-data/common-go/rpsr v0.1.4
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/stretchr/testify v1.11.1
github.com/testcontainers/testcontainers-go v0.38.0
Expand All @@ -56,7 +56,7 @@ require (
github.com/twmb/franz-go/pkg/kfake v0.0.0-20251115002817-3affad808a82
github.com/twmb/franz-go/pkg/kmsg v1.12.0
github.com/twmb/franz-go/pkg/sasl/kerberos v1.1.0
github.com/twmb/franz-go/pkg/sr v1.6.0
github.com/twmb/franz-go/pkg/sr v1.7.0
github.com/twmb/franz-go/plugin/kslog v1.0.0
github.com/twmb/go-cache v1.2.1
github.com/twmb/tlscfg v1.2.1
Expand All @@ -66,7 +66,7 @@ require (
go.vallahaye.net/connect-gateway v0.11.0
golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6
golang.org/x/net v0.51.0
golang.org/x/sync v0.19.0
golang.org/x/sync v0.20.0
golang.org/x/text v0.34.0
google.golang.org/genproto v0.0.0-20251111163417-95abcf5c77ba
google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba
Expand Down
12 changes: 6 additions & 6 deletions backend/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,8 @@ github.com/redpanda-data/common-go/net v0.1.1-0.20240429123545-4da3d2b371f7 h1:M
github.com/redpanda-data/common-go/net v0.1.1-0.20240429123545-4da3d2b371f7/go.mod h1:UJIi/yUxGOBYXUrfUsOkxfYxcb/ll7mZrwae/i+U2kc=
github.com/redpanda-data/common-go/rpadmin v0.2.0 h1:s2MyyY+yq7B17mLjjW17RO81wFlzo856K9IuBpsmvv0=
github.com/redpanda-data/common-go/rpadmin v0.2.0/go.mod h1:qmu76v7RRKgEXLS3UXxZ8KDpObtSNq6RinOIejJNWzw=
github.com/redpanda-data/common-go/rpsr v0.1.2 h1:DThUeyfBH8fkL9WoP1sEbRhT2NVV22zmsTpcCtzfusQ=
github.com/redpanda-data/common-go/rpsr v0.1.2/go.mod h1:2j2416onosg5FKaKz52NooRE+q/9EJqQn0kyTcTXWHc=
github.com/redpanda-data/common-go/rpsr v0.1.4 h1:d9lu5q5wyhZWBYR1GnZkq+eZGKU0qoaSwwybRS9Uk2k=
github.com/redpanda-data/common-go/rpsr v0.1.4/go.mod h1:qVa7b0yaCRdZDn5dcZ9CazqVr4jYbgtOJUywI2X3G3I=
github.com/rickb777/period v1.0.15 h1:nWR4rgCtImT0CXw5kAsjHv+ExCEFt/18zAySOi7pWI8=
github.com/rickb777/period v1.0.15/go.mod h1:3lWluyeZEk6n1jfLCPG4dH3C0N3NxjmYL4Dmcxip3es=
github.com/rickb777/plural v1.4.4 h1:OpZU8uRr9P2NkYAbkLMwlKNVJyJ5HvRcRBFyXGJtKGI=
Expand Down Expand Up @@ -468,8 +468,8 @@ github.com/twmb/franz-go/pkg/kmsg v1.12.0 h1:CbatD7ers1KzDNgJqPbKOq0Bz/WLBdsTH75
github.com/twmb/franz-go/pkg/kmsg v1.12.0/go.mod h1:+DPt4NC8RmI6hqb8G09+3giKObE6uD2Eya6CfqBpeJY=
github.com/twmb/franz-go/pkg/sasl/kerberos v1.1.0 h1:alKdbddkPw3rDh+AwmUEwh6HNYgTvDSFIe/GWYRR9RM=
github.com/twmb/franz-go/pkg/sasl/kerberos v1.1.0/go.mod h1:k8BoBjyUbFj34f0rRbn+Ky12sZFAPbmShrg0karAIMo=
github.com/twmb/franz-go/pkg/sr v1.6.0 h1:YcnD65hmdEuJljSM4O9Hldr/0oi+vrjPGHaRUuwwusA=
github.com/twmb/franz-go/pkg/sr v1.6.0/go.mod h1:64CsHlsQnyFRq1sYPcCmlRrEG3PlLPb6cDddx2wGr28=
github.com/twmb/franz-go/pkg/sr v1.7.0 h1:wHStlO6aOPWWgZ68ZYcdtQe9tRbkcTc1gRLbgs+8QAA=
github.com/twmb/franz-go/pkg/sr v1.7.0/go.mod h1:64CsHlsQnyFRq1sYPcCmlRrEG3PlLPb6cDddx2wGr28=
github.com/twmb/franz-go/plugin/kslog v1.0.0 h1:I64oEmF+0PDvmyLgwrlOtg4mfpSE9GwlcLxM4af2t60=
github.com/twmb/franz-go/plugin/kslog v1.0.0/go.mod h1:8pMjK3OJJJNNYddBSbnXZkIK5dCKFIk9GcVVCDgvnQc=
github.com/twmb/go-cache v1.2.1 h1:yUkLutow4S2x5NMbqFW24o14OsucoFI5Fzmlb6uBinM=
Expand Down Expand Up @@ -572,8 +572,8 @@ golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwE
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
20 changes: 20 additions & 0 deletions backend/pkg/api/handle_schema_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,26 @@ func (api *API) handleDeleteSchemaRegistrySubjectMode() http.HandlerFunc {
}
}

func (api *API) handleGetSchemaRegistryContexts() http.HandlerFunc {
if !api.Cfg.SchemaRegistry.Enabled {
return api.handleSchemaRegistryNotConfigured()
}

return func(w http.ResponseWriter, r *http.Request) {
contexts, err := api.ConsoleSvc.GetSchemaRegistryContexts(r.Context())
if err != nil {
rest.SendRESTError(w, r, api.Logger, &rest.Error{
Err: err,
Status: http.StatusBadGateway,
Message: fmt.Sprintf("Failed to retrieve contexts from the schema registry: %v", err.Error()),
IsSilent: false,
})
return
}
rest.SendResponse(w, r, api.Logger, http.StatusOK, contexts)
}
}

func (api *API) handleGetSchemaSubjects() http.HandlerFunc {
if !api.Cfg.SchemaRegistry.Enabled {
return api.handleSchemaRegistryNotConfigured()
Expand Down
1 change: 1 addition & 0 deletions backend/pkg/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,7 @@ func (api *API) routes() *chi.Mux {
r.Get("/schema-registry/config/{subject}", api.handleGetSchemaRegistrySubjectConfig())
r.Put("/schema-registry/config/{subject}", api.handlePutSchemaRegistrySubjectConfig())
r.Delete("/schema-registry/config/{subject}", api.handleDeleteSchemaRegistrySubjectConfig())
r.Get("/schema-registry/contexts", api.handleGetSchemaRegistryContexts())
r.Get("/schema-registry/subjects", api.handleGetSchemaSubjects())
r.Get("/schema-registry/schemas/types", api.handleGetSchemaRegistrySchemaTypes())
r.Get("/schema-registry/schemas/ids/{id}/versions", api.handleGetSchemaUsagesByID())
Expand Down
51 changes: 49 additions & 2 deletions backend/pkg/console/schema_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ type SchemaRegistrySubject struct {
IsSoftDeleted bool `json:"isSoftDeleted"`
}

// SchemaRegistryContext represents a schema registry context along with
// its mode and compatibility settings.
type SchemaRegistryContext struct {
Name string `json:"name"`
Mode string `json:"mode"`
Compatibility string `json:"compatibility"`
}

// For Schema Registry compatibility level and mode we have 2 custom responses:
// - DEFAULT: there is no per-subject configuration set.
// - UNKNOWN: there is an error, and we are unable to get the configuration.
Expand Down Expand Up @@ -878,6 +886,46 @@ func (s *Service) CheckSchemaRegistryACLSupport(ctx context.Context) bool {
return true
}

// GetSchemaRegistryContexts returns all contexts available in the schema registry,
// enriched with per-context mode and compatibility settings.
func (s *Service) GetSchemaRegistryContexts(ctx context.Context) ([]SchemaRegistryContext, error) {
srClient, err := s.schemaClientFactory.GetSchemaRegistryClient(ctx)
if err != nil {
return nil, err
}

names, err := srClient.Contexts(ctx)
if err != nil {
return nil, err
}

results := make([]SchemaRegistryContext, len(names))
grp, grpCtx := errgroup.WithContext(ctx)
grp.SetLimit(10)

for i, name := range names {
grp.Go(func() error {
// For default context ".", query with empty subject to get global values.
// For named contexts, use qualified syntax :.contextName:
qualifiedSubject := ""
if name != "." {
qualifiedSubject = ":" + name + ":"
}
results[i] = SchemaRegistryContext{
Name: name,
Mode: s.getSubjectMode(grpCtx, srClient, qualifiedSubject),
Compatibility: s.getSubjectCompatibilityLevel(grpCtx, srClient, qualifiedSubject),
}
return nil
})
}

if err := grp.Wait(); err != nil {
return nil, err
}
return results, nil
}

// CheckSchemaRegistryContextsSupport checks if the Schema Registry supports
// the Contexts feature. For Redpanda clusters with Admin API, it checks the
// cluster config. For Kafka clusters, it probes the /contexts endpoint.
Expand Down Expand Up @@ -915,8 +963,7 @@ func (s *Service) CheckSchemaRegistryContextsSupport(ctx context.Context) bool {
return false
}

var contexts []string
err = srClient.Do(ctx, http.MethodGet, "/contexts", nil, &contexts)
_, err = srClient.Contexts(ctx)
if err != nil {
var se *sr.ResponseError
if errors.As(err, &se) && se.StatusCode == http.StatusNotFound {
Expand Down
1 change: 1 addition & 0 deletions backend/pkg/console/servicer.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ type SchemaRegistryServicer interface {
CreateSchemaRegistrySchema(ctx context.Context, subjectName string, schema sr.Schema, params CreateSchemaRequestParams) (*CreateSchemaResponse, error)
ValidateSchemaRegistrySchema(ctx context.Context, subjectName string, version int, schema sr.Schema) (*SchemaRegistrySchemaValidation, error)
GetSchemaUsagesByID(ctx context.Context, schemaID int, subject string) ([]SchemaVersion, error)
GetSchemaRegistryContexts(ctx context.Context) ([]SchemaRegistryContext, error)

// Custom Redpanda-only methods for managing ACLs within the schema registry.

Expand Down
Loading
Loading