Skip to content
Open
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: 6 additions & 0 deletions backend/pkg/console/endpoint_compatibility.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,12 @@ func (s *Service) GetEndpointCompatibility(ctx context.Context) (EndpointCompati
HasRedpandaAPI: true,
RedpandaFeature: redpandaFeatureShadowLinkSchemaRegistrySync,
},
{
URL: "/api/shadow-links/role-sync",
Method: "GET",
HasRedpandaAPI: true,
RedpandaFeature: redpandaFeatureShadowLinkRoleSync,
},
{
URL: "/api/schema-registry/contexts",
Method: "GET",
Expand Down
19 changes: 14 additions & 5 deletions backend/pkg/console/redpanda_feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,22 @@ const (
// redpandaFeatureShadowLinkSchemaRegistrySync represents shadow link Schema Registry
// sync over the Schema Registry API feature.
redpandaFeatureShadowLinkSchemaRegistrySync redpandaFeature = "redpanda_feature_shadow_link_schema_registry_sync"

// redpandaFeatureShadowLinkRoleSync represents shadow link role sync feature.
redpandaFeatureShadowLinkRoleSync redpandaFeature = "redpanda_feature_shadow_link_role_sync"
)

// shadowLinkSchemaRegistrySyncMinVersion is the first Redpanda release whose shadow
// links can sync schemas over the Schema Registry API.
var shadowLinkSchemaRegistrySyncMinVersion = redpanda.MustParseVersion("26.2.0")

// checkShadowLinkSchemaRegistrySyncSupport reports whether the cluster is new enough to
// sync schemas over the Schema Registry API for shadow links.
func checkShadowLinkSchemaRegistrySyncSupport(ctx context.Context, redpandaCl redpandafactory.AdminAPIClient) bool {
// shadowLinkRoleSyncMinVersion is the first Redpanda release whose shadow links
// can sync roles.
var shadowLinkRoleSyncMinVersion = redpanda.MustParseVersion("26.2.0")

// checkClusterVersionAtLeast reports whether the cluster runs at least the given
// Redpanda version, based on the first broker that reports one.
func checkClusterVersionAtLeast(ctx context.Context, redpandaCl redpandafactory.AdminAPIClient, minVersion redpanda.Version) bool {
brokers, err := redpandaCl.Brokers(ctx)
if err != nil {
return false
Expand All @@ -61,7 +68,7 @@ func checkShadowLinkSchemaRegistrySyncSupport(ctx context.Context, redpandaCl re
continue
}
version, err := redpanda.VersionFromString(broker.Version)
return err == nil && version.IsAtLeast(shadowLinkSchemaRegistrySyncMinVersion)
return err == nil && version.IsAtLeast(minVersion)
}

return false
Expand Down Expand Up @@ -100,7 +107,9 @@ func (*Service) checkRedpandaFeature(ctx context.Context, redpandaCl redpandafac
}
return true
case redpandaFeatureShadowLinkSchemaRegistrySync:
return checkShadowLinkSchemaRegistrySyncSupport(ctx, redpandaCl)
return checkClusterVersionAtLeast(ctx, redpandaCl, shadowLinkSchemaRegistrySyncMinVersion)
case redpandaFeatureShadowLinkRoleSync:
return checkClusterVersionAtLeast(ctx, redpandaCl, shadowLinkRoleSyncMinVersion)
case redpandaFeatureSchemaRegistryContexts:
cfg, err := redpandaCl.SingleKeyConfig(ctx, clusterConfigSchemaRegistryQualifiedSubjects)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@

import { AclsStep } from './acls-step';
import { ConsumerOffsetStep } from './consumer-offset-step';
import { RolesStep } from './roles-step';
import { SchemaRegistryStep } from './schema-registry-step';
import { TopicsStep } from './topics-step';

export const ConfigurationStep = () => (
<div className="space-y-4">
<TopicsStep />
<AclsStep />
<RolesStep />
<ConsumerOffsetStep />
<SchemaRegistryStep />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ describe('ConsumerOffsetStep', () => {
expect(screen.getByTestId('consumer-filter-0-exclude-prefix')).toBeInTheDocument();

// Verify the text content of the tabs
expect(screen.getByTestId('consumer-filter-0-include-specific')).toHaveTextContent('Include specific topics');
expect(screen.getByTestId('consumer-filter-0-include-specific')).toHaveTextContent(
'Include specific consumer groups'
);
expect(screen.getByTestId('consumer-filter-0-include-prefix')).toHaveTextContent('Include starting with');
expect(screen.getByTestId('consumer-filter-0-exclude-specific')).toHaveTextContent('Exclude specific');
expect(screen.getByTestId('consumer-filter-0-exclude-prefix')).toHaveTextContent('Exclude starting with');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ import { useWatch } from 'react-hook-form';
import { Item } from '../../../../redpanda-ui/components/item';
import { getFilterTypeLabel } from '../../shadowlink-helpers';

const RESOURCE_TYPE_BY_PREFIX: Record<string, string> = {
topics: 'topics',
roles: 'roles',
consumers: 'consumer groups',
};

type FilterItemProps<TFieldValues extends FieldValues> = {
control: Control<TFieldValues>;
index: number;
Expand Down Expand Up @@ -55,11 +61,11 @@ export const FilterItem = <TFieldValues extends FieldValues>({
const showMatchAllMessage =
patternValue === PatternType.LITERAL && filterValue === FilterType.INCLUDE && nameValue === '*';

const resourceType = fieldNamePrefix === 'topics' ? 'topics' : 'consumer groups';
const resourceType = RESOURCE_TYPE_BY_PREFIX[fieldNamePrefix] ?? 'consumer groups';

// Resume/summary view (non-editable)
if (!viewType) {
const filterLabel = getFilterTypeLabel(patternValue, filterValue);
const filterLabel = getFilterTypeLabel(patternValue, filterValue, resourceType);

return (
<div>
Expand Down Expand Up @@ -148,7 +154,7 @@ export const FilterItem = <TFieldValues extends FieldValues>({
data-testid={dataTestId ? `${dataTestId}-include-specific` : undefined}
value="include-specific"
>
Include specific topics
Include specific {resourceType}
</TabsTrigger>
<TabsTrigger
data-testid={dataTestId ? `${dataTestId}-include-prefix` : undefined}
Expand Down
Loading
Loading