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
14 changes: 8 additions & 6 deletions src/go/rpk/pkg/cli/cluster/quotas/alter.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ package quotas

import (
"fmt"
"maps"
"slices"
"strconv"
"strings"

Expand Down Expand Up @@ -49,8 +51,8 @@ This command allows you to add or delete a client quota.
A client quota consists of an entity (to whom the quota is applied) and a quota
type (what is being applied).

There are two entity types supported by Redpanda: client ID and client ID
prefix.
There are three entity types supported by Redpanda: user, client ID, and
client ID prefix.

Assigning quotas to default entity types is possible using the '--default' flag.

Expand Down Expand Up @@ -95,8 +97,8 @@ Remove quota (producer_byte_rate) from client ID 'foo':
}
k, v := split[0], split[1]
k = strings.ToLower(k)
if !anyValidTypes[k] {
out.Die("name type %q is invalid (allowed: client-id, client-id-prefix)", split[0])
if _, ok := anyValidTypes[k]; !ok {
out.Die("name type %q is invalid (allowed: %v)", k, strings.Join(slices.Collect(maps.Keys(anyValidTypes)), ", "))
}
nameMap[k] = true
entity = append(entity, kadm.ClientQuotaEntityComponent{
Expand All @@ -105,8 +107,8 @@ Remove quota (producer_byte_rate) from client ID 'foo':
})
}
for _, def := range defaults {
if !defaultValidTypes[def] {
out.Die("default type %q is invalid (allowed: client-id)", def)
if _, ok := defaultValidTypes[def]; !ok {
out.Die("default type %q is invalid (allowed: %v)", def, strings.Join(slices.Collect(maps.Keys(defaultValidTypes)), ", "))
}
if nameMap[def] {
out.Die("default type %q was previously defined in --name, you can only set it once", def)
Expand Down
14 changes: 8 additions & 6 deletions src/go/rpk/pkg/cli/cluster/quotas/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ package quotas

import (
"fmt"
"maps"
"slices"
"strconv"
"strings"

Expand Down Expand Up @@ -88,8 +90,8 @@ Describe client quotas for a given client ID prefix 'bar.':
}
k, v := split[0], split[1]
k = strings.ToLower(k)
if !anyValidTypes[k] {
out.Die("name type %q is invalid (allowed: client-id, client-id-prefix)", split[0])
if _, ok := anyValidTypes[k]; !ok {
out.Die("name type %q is invalid (allowed: %v)", k, strings.Join(slices.Collect(maps.Keys(anyValidTypes)), ", "))
}
reqQuotas = append(reqQuotas, kadm.DescribeClientQuotaComponent{
Type: k,
Expand All @@ -99,8 +101,8 @@ Describe client quotas for a given client ID prefix 'bar.':
}
for _, def := range defaults {
k := strings.ToLower(def)
if !defaultValidTypes[k] {
out.Die("default type %q is invalid (allowed: client-id)", def)
if _, ok := defaultValidTypes[k]; !ok {
out.Die("default type %q is invalid (allowed: %v)", def, strings.Join(slices.Collect(maps.Keys(defaultValidTypes)), ", "))
}
reqQuotas = append(reqQuotas, kadm.DescribeClientQuotaComponent{
Type: k,
Expand All @@ -109,8 +111,8 @@ Describe client quotas for a given client ID prefix 'bar.':
}
for _, a := range anyFlag {
k := strings.ToLower(a)
if !anyValidTypes[k] {
out.Die("'any' type %q is invalid (allowed: client-id, client-id-prefix)", a)
if _, ok := anyValidTypes[k]; !ok {
out.Die("'any' type %q is invalid (allowed: %v)", a, strings.Join(slices.Collect(maps.Keys(anyValidTypes)), ", "))
}
reqQuotas = append(reqQuotas, kadm.DescribeClientQuotaComponent{
Type: k,
Expand Down
22 changes: 9 additions & 13 deletions src/go/rpk/pkg/cli/cluster/quotas/quotas.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,18 @@ func NewCommand(fs afero.Fs, p *config.Params) *cobra.Command {
}

// anyValidTypes are the types allowed in --name and --any flags.
var anyValidTypes = map[string]bool{
// Supported by Redpanda.
"client-id": true,
"client-id-prefix": true,
// Not supported by Redpanda yet.
"user": true,
"ip": true,
var anyValidTypes = map[string]struct{}{
"client-id": {},
"client-id-prefix": {},
"user": {},
// IP is not supported by Redpanda yet.
}

// defaultValidTypes are the types allowed in --default flag.
var defaultValidTypes = map[string]bool{
// Supported by Redpanda.
"client-id": true,
// Not supported by Redpanda yet.
"user": true,
"ip": true,
var defaultValidTypes = map[string]struct{}{
"client-id": {},
"user": {},
// IP is not supported by Redpanda yet.
}

type entityData struct {
Expand Down
26 changes: 23 additions & 3 deletions tests/rptest/tests/rpk_cluster_quota_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ def test_import_describe_quotas(self):
self._rpk.alter_cluster_quotas(
name=["client-id-prefix=foo-"], add=["consumer_byte_rate=2222"]
)
self._rpk.alter_cluster_quotas(
name=["user=bar"], add=["controller_mutation_rate=512"]
)

q2 = self._rpk.describe_cluster_quotas()
assert len(q2["quotas"]) == 2 # Quick check, just that we have something.
assert len(q2["quotas"]) == 3 # Quick check, just that we have something.

# Same values, NoOp:
import1 = """
Expand Down Expand Up @@ -71,14 +74,28 @@ def test_import_describe_quotas(self):
"value":"11111"
}
]
}
},
{
"entity":[
{
"name":"bar",
"type":"user"
}
],
"values":[
{
"key":"controller_mutation_rate",
"value":"512"
}
]
},
]
}
"""
out = self._rpk.import_cluster_quota(import1, output_format="text")
assert "No changes detected from import" in out

# Remove 1 (default client-id), Add 1 (producer byte rate).
# Remove 2 (default client-id and user), Add 1 (producer byte rate).
import2 = """
{
"quotas":[
Expand Down Expand Up @@ -121,6 +138,9 @@ def assertChanges(quotas, entity, quotaType, old, new):
assertChanges(
out, "client-id=<default>", "producer_byte_rate", old="11111", new="-"
) # New Value as '-' means it was deleted
assertChanges(
out, "user=bar", "controller_mutation_rate", old="512", new="-"
)
assertChanges(
out, "client-id-prefix=foo-", "producer_byte_rate", old="-", new="3333"
)
Expand Down
Loading