Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpk: Enable key=value notation for every set command #13325

Merged
merged 2 commits into from
Sep 11, 2023
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
18 changes: 15 additions & 3 deletions src/go/rpk/pkg/cli/cluster/config/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package config
import (
"errors"
"fmt"
"strings"

"github.com/redpanda-data/redpanda/src/go/rpk/pkg/adminapi"
"github.com/redpanda-data/redpanda/src/go/rpk/pkg/config"
Expand Down Expand Up @@ -50,11 +51,22 @@ func newSetCommand(fs afero.Fs, p *config.Params) *cobra.Command {
This command is provided for use in scripts. For interactive editing, or bulk
changes, use the 'edit' and 'import' commands respectively.

You may also use <key>=<value> notation for setting configuration properties:

rpk cluster config set delete_retention_ms=-1

If an empty string is given as the value, the property is reset to its default.`,
Args: cobra.ExactArgs(2),
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
key := args[0]
value := args[1]
var key, value string
if len(args) == 1 && strings.Contains(args[0], "=") {
kv := strings.SplitN(args[0], "=", 2)
key, value = kv[0], kv[1]
} else if len(args) == 2 {
key, value = args[0], args[1]
} else {
out.Die("invalid arguments: %v, please use one of 'rpk cluster config set <key> <value>' or 'rpk cluster config set <key>=<value>'", args)
}

p, err := p.LoadVirtualProfile(fs)
out.MaybeDie(err, "unable to load config: %v", err)
Expand Down
19 changes: 17 additions & 2 deletions src/go/rpk/pkg/cli/redpanda/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"errors"
"fmt"
"net"
"strings"

"github.com/redpanda-data/redpanda/src/go/rpk/pkg/cobraext"
"github.com/redpanda-data/redpanda/src/go/rpk/pkg/config"
Expand Down Expand Up @@ -67,13 +68,27 @@ Indexing can be used to set specific items in an array. You can index one past
the end of an array to extend it:

rpk redpanda config set redpanda.advertised_kafka_api[1] '{address: 0.0.0.0, port: 9092}'

You may also use <key>=<value> notation for setting configuration properties:

rpk redpanda config set redpanda.kafka_api[0].port=9092
`,
Args: cobra.ExactArgs(2),
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
cfg, err := p.Load(fs)
out.MaybeDie(err, "unable to load config: %v", err)

var key, value string
if len(args) == 1 && strings.Contains(args[0], "=") {
kv := strings.SplitN(args[0], "=", 2)
key, value = kv[0], kv[1]
} else if len(args) == 2 {
key, value = args[0], args[1]
} else {
out.Die("invalid arguments: %v, please use one of 'rpk redpanda config set <key> <value>' or 'rpk redpanda config set <key>=<value>'", args)
}
y := cfg.ActualRedpandaYamlOrDefaults() // we set fields in the raw file without writing env / flag overrides
err = config.Set(y, args[0], args[1])
err = config.Set(y, key, value)
out.MaybeDie(err, "unable to set %q:%v", args[0], err)
err = y.Write(fs)
out.MaybeDieErr(err)
Expand Down
97 changes: 85 additions & 12 deletions src/go/rpk/pkg/cli/redpanda/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ func TestSetCommand(t *testing.T) {
for _, test := range []struct {
name string
cfgFile string
exp string
args []string
exp string
}{
{
name: "set without config file on disk",
Expand All @@ -269,8 +269,7 @@ pandaproxy: {}
schema_registry: {}
`,
args: []string{"redpanda.rack", "redpanda-rack"},
},
{
}, {
name: "set with loaded config",
cfgFile: `redpanda:
data_directory: data/dir
Expand Down Expand Up @@ -310,30 +309,104 @@ rpk:
tune_cpu: true
`,
args: []string{"rpk.tune_cpu", "true"},
}, {
name: "set with =",
args: []string{"rpk.tune_cpu=true"},
cfgFile: `redpanda:
data_directory: data/dir
rack: redpanda-rack
seed_servers: []
rpc_server:
address: 0.0.0.0
port: 33145
kafka_api:
- address: 0.0.0.0
port: 9092
admin:
- address: 0.0.0.0
port: 9644
developer_mode: true
rpk:
tune_network: true
tune_disk_scheduler: true
`,
exp: `redpanda:
data_directory: data/dir
rack: redpanda-rack
seed_servers: []
rpc_server:
address: 0.0.0.0
port: 33145
kafka_api:
- address: 0.0.0.0
port: 9092
admin:
- address: 0.0.0.0
port: 9644
developer_mode: true
rpk:
tune_network: true
tune_disk_scheduler: true
tune_cpu: true
`,
}, {
name: "set with = negative number",
args: []string{"redpanda.rpc_server.port=-1"},
cfgFile: `redpanda:
data_directory: data/dir
rack: redpanda-rack
seed_servers: []
rpc_server:
address: 0.0.0.0
port: 33145
kafka_api:
- address: 0.0.0.0
port: 9092
admin:
- address: 0.0.0.0
port: 9644
developer_mode: true
rpk:
tune_network: true
tune_disk_scheduler: true
`,
exp: `redpanda:
data_directory: data/dir
rack: redpanda-rack
seed_servers: []
rpc_server:
address: 0.0.0.0
port: -1
kafka_api:
- address: 0.0.0.0
port: 9092
admin:
- address: 0.0.0.0
port: 9644
developer_mode: true
rpk:
tune_network: true
tune_disk_scheduler: true
`,
},
} {
fs := afero.NewMemMapFs()

// We create a config file in default redpanda location
if test.cfgFile != "" {
err := afero.WriteFile(fs, "/etc/redpanda/redpanda.yaml", []byte(test.cfgFile), 0o644)
if err != nil {
t.Errorf("unexpected failure writing passed config file: %v", err)
}
require.NoError(t, err, "unexpected failure writing passed config file: %v", err)
}

c := set(fs, new(config.Params))
c.SetArgs(test.args)
err := c.Execute()
if err != nil {
t.Errorf("error during command execution: %v", err)
}
require.NoError(t, err, "error during command execution: %v", err)

// Read back from that default location and compare.
file, err := afero.ReadFile(fs, "/etc/redpanda/redpanda.yaml")
if err != nil {
t.Errorf("unexpected failure reading config file: %v", err)
}
require.NoError(t, err, "unexpected failure reading config file: %v", err)

require.Equal(t, test.exp, string(file))
}
}
Loading