diff --git a/cmd/scw/testdata/test-all-usage-redis-version-list-settings-usage.golden b/cmd/scw/testdata/test-all-usage-redis-version-list-settings-usage.golden new file mode 100644 index 0000000000..52752e6146 --- /dev/null +++ b/cmd/scw/testdata/test-all-usage-redis-version-list-settings-usage.golden @@ -0,0 +1,23 @@ +🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲 +🟥🟥🟥 STDERR️️ 🟥🟥🟥️ +List available settings from a Redis™ version. + +USAGE: + scw redis version list-settings [arg=value ...] + +EXAMPLES: + List settings for Redis™ 7.2.11 + scw redis version list-settings version=7.2.11 + +ARGS: + version Redis™ engine version + [zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | fr-par-2 | nl-ams-1 | nl-ams-2 | pl-waw-1 | pl-waw-2) + +FLAGS: + -h, --help help for list-settings + +GLOBAL FLAGS: + -c, --config string The path to the config file + -D, --debug Enable debug mode + -o, --output string Output format: json or human, see 'scw help output' for more info (default "human") + -p, --profile string The config profile to use diff --git a/cmd/scw/testdata/test-all-usage-redis-version-usage.golden b/cmd/scw/testdata/test-all-usage-redis-version-usage.golden index 8bf12a68d7..c17299d013 100644 --- a/cmd/scw/testdata/test-all-usage-redis-version-usage.golden +++ b/cmd/scw/testdata/test-all-usage-redis-version-usage.golden @@ -6,7 +6,8 @@ USAGE: scw redis version AVAILABLE COMMANDS: - list List available Redis™ versions + list List available Redis™ versions + list-settings List available settings from a Redis™ version FLAGS: -h, --help help for version diff --git a/docs/commands/redis.md b/docs/commands/redis.md index cfea4838e8..24f03c771c 100644 --- a/docs/commands/redis.md +++ b/docs/commands/redis.md @@ -33,6 +33,7 @@ This API allows you to manage your Managed Databases for Redis™. - [Set advanced settings](#set-advanced-settings) - [Redis™ version management commands](#redis™-version-management-commands) - [List available Redis™ versions](#list-available-redis™-versions) + - [List available settings from a Redis™ version](#list-available-settings-from-a-redis™-version) ## Access Control List (ACL) management commands @@ -629,3 +630,33 @@ scw redis version list [arg=value ...] +### List available settings from a Redis™ version + +List available settings from a Redis™ version. + +**Usage:** + +``` +scw redis version list-settings [arg=value ...] +``` + + +**Args:** + +| Name | | Description | +|------|---|-------------| +| version | Required | Redis™ engine version | +| zone | Default: `fr-par-1`
One of: `fr-par-1`, `fr-par-2`, `nl-ams-1`, `nl-ams-2`, `pl-waw-1`, `pl-waw-2` | Zone to target. If none is passed will use default zone from the config | + + +**Examples:** + + +List settings for Redis™ 7.2.11 +``` +scw redis version list-settings version=7.2.11 +``` + + + + diff --git a/internal/namespaces/redis/v1/custom.go b/internal/namespaces/redis/v1/custom.go index 50c46b3ec7..9d4e79271e 100644 --- a/internal/namespaces/redis/v1/custom.go +++ b/internal/namespaces/redis/v1/custom.go @@ -21,6 +21,7 @@ func GetCommands() *core.Commands { cmds.MustFind("redis", "cluster", "migrate").Override(redisClusterMigrateBuilder) cmds.Merge(core.NewCommands(redisACLUpdateCommand())) + cmds.Merge(core.NewCommands(redisVersionSettingsCommand())) return cmds } diff --git a/internal/namespaces/redis/v1/custom_version_settings.go b/internal/namespaces/redis/v1/custom_version_settings.go new file mode 100644 index 0000000000..730b480f3f --- /dev/null +++ b/internal/namespaces/redis/v1/custom_version_settings.go @@ -0,0 +1,67 @@ +package redis + +import ( + "context" + "reflect" + + "github.com/scaleway/scaleway-cli/v2/core" + "github.com/scaleway/scaleway-sdk-go/api/redis/v1" + "github.com/scaleway/scaleway-sdk-go/scw" +) + +func redisVersionSettingsCommand() *core.Command { + type versionSettingsArgs struct { + Version string + Zone scw.Zone + } + + return &core.Command{ + Short: "List available settings from a Redis™ version", + Long: "List available settings from a Redis™ version.", + Namespace: "redis", + Resource: "version", + Verb: "list-settings", + ArgsType: reflect.TypeOf(versionSettingsArgs{}), + ArgSpecs: core.ArgSpecs{ + { + Name: "version", + Short: "Redis™ engine version", + Required: true, + }, + core.ZoneArgSpec( + scw.ZoneFrPar1, + scw.ZoneFrPar2, + scw.ZoneNlAms1, + scw.ZoneNlAms2, + scw.ZonePlWaw1, + scw.ZonePlWaw2, + ), + }, + Examples: []*core.Example{ + { + Short: "List settings for Redis™ 7.2.11", + ArgsJSON: `{"version": "7.2.11"}`, + }, + }, + Run: func(ctx context.Context, argsI any) (any, error) { + args := argsI.(*versionSettingsArgs) + api := redis.NewAPI(core.ExtractClient(ctx)) + + resp, err := api.ListClusterVersions(&redis.ListClusterVersionsRequest{ + Zone: args.Zone, + Version: &args.Version, + }) + if err != nil { + return nil, err + } + + for _, version := range resp.Versions { + if version.Version == args.Version { + return version.AvailableSettings, nil + } + } + + return []*redis.AvailableClusterSetting{}, nil + }, + } +} diff --git a/internal/namespaces/redis/v1/custom_version_settings_test.go b/internal/namespaces/redis/v1/custom_version_settings_test.go new file mode 100644 index 0000000000..31e3e75882 --- /dev/null +++ b/internal/namespaces/redis/v1/custom_version_settings_test.go @@ -0,0 +1,32 @@ +package redis_test + +import ( + "testing" + + "github.com/scaleway/scaleway-cli/v2/core" + "github.com/scaleway/scaleway-cli/v2/internal/namespaces/redis/v1" + redisSDK "github.com/scaleway/scaleway-sdk-go/api/redis/v1" + "github.com/stretchr/testify/assert" +) + +func TestRedisVersionSettingsCommand(t *testing.T) { + t.Run("List settings for Redis version", core.Test(&core.TestConfig{ + Commands: redis.GetCommands(), + Cmd: "scw redis version list-settings version=7.2.11", + Check: core.TestCheckCombine( + core.TestCheckExitCode(0), + core.TestCheckGolden(), + func(t *testing.T, ctx *core.CheckFuncCtx) { + t.Helper() + if ctx.Result != nil { + settings := ctx.Result.([]*redisSDK.AvailableClusterSetting) + assert.NotEmpty(t, settings, "should return at least one setting") + // Verify that settings have the expected structure + for _, setting := range settings { + assert.NotEmpty(t, setting.Name, "setting should have a name") + } + } + }, + ), + })) +} diff --git a/internal/namespaces/redis/v1/testdata/test-redis-version-settings-command-list-settings-for-redis-version.cassette.yaml b/internal/namespaces/redis/v1/testdata/test-redis-version-settings-command-list-settings-for-redis-version.cassette.yaml new file mode 100644 index 0000000000..cd6cc25e5c --- /dev/null +++ b/internal/namespaces/redis/v1/testdata/test-redis-version-settings-command-list-settings-for-redis-version.cassette.yaml @@ -0,0 +1,81 @@ +--- +version: 1 +interactions: +- request: + body: '{"total_count":1, "versions":[{"version":"7.2.11", "end_of_life_at":"2026-02-28T00:00:00Z", + "available_settings":[{"name":"tcp-keepalive", "default_value":"300", "type":"INT", + "description":"The specified value (in seconds) is the period used to send ACKs.", + "max_value":65536, "min_value":null, "regex":null, "deprecated":false}, {"name":"maxclients", + "default_value":"10000", "type":"INT", "description":"Set the max number of + connected clients at the same time.", "max_value":65536, "min_value":100, "regex":null, + "deprecated":false}, {"name":"maxmemory-policy", "default_value":"noeviction", + "type":"STRING", "description":"How Redis will select what to remove when maxmemory + is reached: https://redis.io/topics/lru-cache.", "max_value":null, "min_value":null, + "regex":"volatile-lru|allkeys-lru|volatile-lfu|allkeys-lfu|volatile-random|allkeys-random|volatile-ttl|noeviction", + "deprecated":false}, {"name":"databases", "default_value":"16", "type":"INT", + "description":"Set number of Redis databases", "max_value":128, "min_value":1, + "regex":null, "deprecated":false}, {"name":"notify-keyspace-events", "default_value":"\"\"", + "type":"STRING", "description":"Configure the keyspace event notification feature", + "max_value":null, "min_value":null, "regex":"^(?:([KEg$lshzxetdnm])(?!.*\\1))+$", + "deprecated":false}, {"name":"disable-save", "default_value":"false", "type":"BOOLEAN", + "description":"Disable Redis rdb persistence file on disk", "max_value":null, + "min_value":null, "regex":null, "deprecated":false}, {"name":"slowlog-log-slower-than", + "default_value":"10000", "type":"INT", "description":"Log queries that exceed + this duration in microseconds (set to -1 to disable)", "max_value":100000000, + "min_value":-1, "regex":null, "deprecated":false}, {"name":"slowlog-max-len", + "default_value":"128", "type":"INT", "description":"Maximum length of the slow + log", "max_value":10000, "min_value":1, "regex":null, "deprecated":false}], + "logo_url":"https://s3.fr-par.scw.cloud/scw-rkv-logos/logo.svg", "zone":"fr-par-1"}]}' + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; amd64) cli-e2e-test + url: https://api.scaleway.com/redis/v1/zones/fr-par-1/cluster-versions?include_beta=false&include_deprecated=false&include_disabled=false&version=7.2.11 + method: GET + response: + body: '{"total_count":1, "versions":[{"version":"7.2.11", "end_of_life_at":"2026-02-28T00:00:00Z", + "available_settings":[{"name":"tcp-keepalive", "default_value":"300", "type":"INT", + "description":"The specified value (in seconds) is the period used to send ACKs.", + "max_value":65536, "min_value":null, "regex":null, "deprecated":false}, {"name":"maxclients", + "default_value":"10000", "type":"INT", "description":"Set the max number of + connected clients at the same time.", "max_value":65536, "min_value":100, "regex":null, + "deprecated":false}, {"name":"maxmemory-policy", "default_value":"noeviction", + "type":"STRING", "description":"How Redis will select what to remove when maxmemory + is reached: https://redis.io/topics/lru-cache.", "max_value":null, "min_value":null, + "regex":"volatile-lru|allkeys-lru|volatile-lfu|allkeys-lfu|volatile-random|allkeys-random|volatile-ttl|noeviction", + "deprecated":false}, {"name":"databases", "default_value":"16", "type":"INT", + "description":"Set number of Redis databases", "max_value":128, "min_value":1, + "regex":null, "deprecated":false}, {"name":"notify-keyspace-events", "default_value":"\"\"", + "type":"STRING", "description":"Configure the keyspace event notification feature", + "max_value":null, "min_value":null, "regex":"^(?:([KEg$lshzxetdnm])(?!.*\\1))+$", + "deprecated":false}, {"name":"disable-save", "default_value":"false", "type":"BOOLEAN", + "description":"Disable Redis rdb persistence file on disk", "max_value":null, + "min_value":null, "regex":null, "deprecated":false}, {"name":"slowlog-log-slower-than", + "default_value":"10000", "type":"INT", "description":"Log queries that exceed + this duration in microseconds (set to -1 to disable)", "max_value":100000000, + "min_value":-1, "regex":null, "deprecated":false}, {"name":"slowlog-max-len", + "default_value":"128", "type":"INT", "description":"Maximum length of the slow + log", "max_value":10000, "min_value":1, "regex":null, "deprecated":false}], + "logo_url":"https://s3.fr-par.scw.cloud/scw-rkv-logos/logo.svg", "zone":"fr-par-1"}]}' + headers: + Content-Length: + - "2025" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Thu, 27 Nov 2025 15:34:55 GMT + Server: + - Scaleway API Gateway (fr-par-2;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - e2b94d11-4e80-4a3a-910f-1d4abd26d3f5 + status: 200 OK + code: 200 + duration: "" diff --git a/internal/namespaces/redis/v1/testdata/test-redis-version-settings-command-list-settings-for-redis-version.golden b/internal/namespaces/redis/v1/testdata/test-redis-version-settings-command-list-settings-for-redis-version.golden new file mode 100644 index 0000000000..e76f00ce9a --- /dev/null +++ b/internal/namespaces/redis/v1/testdata/test-redis-version-settings-command-list-settings-for-redis-version.golden @@ -0,0 +1,94 @@ +🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲 +🟩🟩🟩 STDOUT️ 🟩🟩🟩️ +NAME DEFAULT VALUE TYPE DESCRIPTION MAX VALUE MIN VALUE REGEX DEPRECATED +tcp-keepalive 300 INT The specified value (in seconds) is the period used to send ACKs. 65536 - - false +maxclients 10000 INT Set the max number of connected clients at the same time. 65536 100 - false +maxmemory-policy noeviction STRING How Redis will select what to remove when maxmemory is reached: https://redis.io/topics/lru-cache. - - volatile-lru|allkeys-lru|volatile-lfu|allkeys-lfu|volatile-random|allkeys-random|volatile-ttl|noeviction false +databases 16 INT Set number of Redis databases 128 1 - false +notify-keyspace-events "" STRING Configure the keyspace event notification feature - - ^(?:([KEg$lshzxetdnm])(?!.*\1))+$ false +disable-save false BOOLEAN Disable Redis rdb persistence file on disk - - - false +slowlog-log-slower-than 10000 INT Log queries that exceed this duration in microseconds (set to -1 to disable) 100000000 -1 - false +slowlog-max-len 128 INT Maximum length of the slow log 10000 1 - false +🟩🟩🟩 JSON STDOUT 🟩🟩🟩 +[ + { + "name": "tcp-keepalive", + "default_value": "300", + "type": "INT", + "description": "The specified value (in seconds) is the period used to send ACKs.", + "max_value": 65536, + "min_value": null, + "regex": null, + "deprecated": false + }, + { + "name": "maxclients", + "default_value": "10000", + "type": "INT", + "description": "Set the max number of connected clients at the same time.", + "max_value": 65536, + "min_value": 100, + "regex": null, + "deprecated": false + }, + { + "name": "maxmemory-policy", + "default_value": "noeviction", + "type": "STRING", + "description": "How Redis will select what to remove when maxmemory is reached: https://redis.io/topics/lru-cache.", + "max_value": null, + "min_value": null, + "regex": "volatile-lru|allkeys-lru|volatile-lfu|allkeys-lfu|volatile-random|allkeys-random|volatile-ttl|noeviction", + "deprecated": false + }, + { + "name": "databases", + "default_value": "16", + "type": "INT", + "description": "Set number of Redis databases", + "max_value": 128, + "min_value": 1, + "regex": null, + "deprecated": false + }, + { + "name": "notify-keyspace-events", + "default_value": "\"\"", + "type": "STRING", + "description": "Configure the keyspace event notification feature", + "max_value": null, + "min_value": null, + "regex": "^(?:([KEg$lshzxetdnm])(?!.*\\1))+$", + "deprecated": false + }, + { + "name": "disable-save", + "default_value": "false", + "type": "BOOLEAN", + "description": "Disable Redis rdb persistence file on disk", + "max_value": null, + "min_value": null, + "regex": null, + "deprecated": false + }, + { + "name": "slowlog-log-slower-than", + "default_value": "10000", + "type": "INT", + "description": "Log queries that exceed this duration in microseconds (set to -1 to disable)", + "max_value": 100000000, + "min_value": -1, + "regex": null, + "deprecated": false + }, + { + "name": "slowlog-max-len", + "default_value": "128", + "type": "INT", + "description": "Maximum length of the slow log", + "max_value": 10000, + "min_value": 1, + "regex": null, + "deprecated": false + } +]