Skip to content

Commit

Permalink
feat(dbaas): add Valkey support, deprecate Redis (#344)
Browse files Browse the repository at this point in the history
  • Loading branch information
kangasta authored Nov 14, 2024
1 parent a3925b7 commit a8a0094
Show file tree
Hide file tree
Showing 11 changed files with 1,924 additions and 205 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

### Added
- managed databases: add support for Valkey

### Deprecated
- managed databases: deprecate Redis

## [8.11.0]

### Added
Expand Down
77 changes: 63 additions & 14 deletions upcloud/managed_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,11 @@ const (
ManagedDatabaseServiceTypePostgreSQL ManagedDatabaseServiceType = "pg"
// ManagedDatabaseServiceTypeMySQL references a MySQL type of database instance
ManagedDatabaseServiceTypeMySQL ManagedDatabaseServiceType = "mysql"
// Deprecated: Prefer Valkey for new key-value store instances.
// ManagedDatabaseServiceTypeRedis references a Redis type of database instance
ManagedDatabaseServiceTypeRedis ManagedDatabaseServiceType = "redis"
// ManagedDatabaseServiceTypeValkey references a Valkey type of database instance
ManagedDatabaseServiceTypeValkey ManagedDatabaseServiceType = "valkey"
// ManagedDatabaseServiceTypeOpenSearch references an OpenSearch type of database instance
ManagedDatabaseServiceTypeOpenSearch ManagedDatabaseServiceType = "opensearch"
)
Expand Down Expand Up @@ -238,7 +241,9 @@ type ManagedDatabaseComponent struct {
type ManagedDatabaseSessions struct {
MySQL []ManagedDatabaseSessionMySQL `json:"mysql,omitempty"`
PostgreSQL []ManagedDatabaseSessionPostgreSQL `json:"pg,omitempty"`
Redis []ManagedDatabaseSessionRedis `json:"redis,omitempty"`
// Deprecated: Redis support will be removed in favor of Valkey.
Redis []ManagedDatabaseSessionRedis `json:"redis,omitempty"`
Valkey []ManagedDatabaseSessionValkey `json:"valkey,omitempty"`
}

// ManagedDatabaseSessionMySQL represents a session in a managed MySQL database instance.
Expand Down Expand Up @@ -278,6 +283,7 @@ type ManagedDatabaseSessionPostgreSQL struct {
XactStart *time.Time `json:"xact_start"`
}

// Deprecated: Redis support will be removed in favor of Valkey.
// ManagedDatabaseSessionRedis represents a session in a managed Redis database instance.
type ManagedDatabaseSessionRedis struct {
ActiveChannelSubscriptions int `json:"active_channel_subscriptions"`
Expand All @@ -299,6 +305,27 @@ type ManagedDatabaseSessionRedis struct {
QueryBufferFree int `json:"query_buffer_free"`
}

// ManagedDatabaseSessionValkey represents a session in a managed Valkey database instance.
type ManagedDatabaseSessionValkey struct {
ActiveChannelSubscriptions int `json:"active_channel_subscriptions"`
ActiveDatabase string `json:"active_database"`
ActivePatternMatchingChannelSubscriptions int `json:"active_pattern_matching_channel_subscriptions"`
ApplicationName string `json:"application_name"`
ClientAddr string `json:"client_addr"`
ConnectionAge time.Duration `json:"connection_age"`
ConnectionIdle time.Duration `json:"connection_idle"`
Flags []string `json:"flags"`
FlagsRaw string `json:"flags_raw"`
Id string `json:"id"`
MultiExecCommands int `json:"multi_exec_commands"`
OutputBuffer int `json:"output_buffer"`
OutputBufferMemory int `json:"output_buffer_memory"`
OutputListLength int `json:"output_list_length"`
Query string `json:"query"`
QueryBuffer int `json:"query_buffer"`
QueryBufferFree int `json:"query_buffer_free"`
}

// ManagedDatabaseMaintenanceTime represents the set time of week when automatic maintenance operations are allowed
type ManagedDatabaseMaintenanceTime struct {
DayOfWeek string `json:"dow"`
Expand Down Expand Up @@ -644,24 +671,34 @@ type ManagedDatabaseUser struct {
Type ManagedDatabaseUserType `json:"type,omitempty"`
// Password field is only visible when querying an individual user. It is omitted in main service view and in
// get all users view.
Password string `json:"password,omitempty"`
Username string `json:"username,omitempty"`
PGAccessControl *ManagedDatabaseUserPGAccessControl `json:"pg_access_control,omitempty"`
Password string `json:"password,omitempty"`
Username string `json:"username,omitempty"`
PGAccessControl *ManagedDatabaseUserPGAccessControl `json:"pg_access_control,omitempty"`
// Deprecated: Redis support will be removed in favor of Valkey.
RedisAccessControl *ManagedDatabaseUserRedisAccessControl `json:"redis_access_control,omitempty"`
ValkeyAccessControl *ManagedDatabaseUserValkeyAccessControl `json:"valkey_access_control,omitempty"`
OpenSearchAccessControl *ManagedDatabaseUserOpenSearchAccessControl `json:"opensearch_access_control,omitempty"`
}

type ManagedDatabaseUserPGAccessControl struct {
AllowReplication *bool `json:"allow_replication,omitempty"`
}

// Deprecated: Redis support will be removed in favor of Valkey.
type ManagedDatabaseUserRedisAccessControl struct {
Categories *[]string `json:"categories,omitempty"`
Channels *[]string `json:"channels,omitempty"`
Commands *[]string `json:"commands,omitempty"`
Keys *[]string `json:"keys,omitempty"`
}

type ManagedDatabaseUserValkeyAccessControl struct {
Categories *[]string `json:"categories,omitempty"`
Channels *[]string `json:"channels,omitempty"`
Commands *[]string `json:"commands,omitempty"`
Keys *[]string `json:"keys,omitempty"`
}

type ManagedDatabaseUserOpenSearchAccessControl struct {
Rules *[]ManagedDatabaseUserOpenSearchAccessControlRule `json:"rules,omitempty"`
}
Expand Down Expand Up @@ -753,13 +790,15 @@ type ManagedDatabaseServicePlan struct {
BackupConfigMySQL *ManagedDatabaseBackupConfigMySQL `json:"backup_config_mysql,omitempty"`
BackupConfigOpenSearch *ManagedDatabaseBackupConfigOpenSearch `json:"backup_config_opensearch,omitempty"`
BackupConfigPostgreSQL *ManagedDatabaseBackupConfigPostgreSQL `json:"backup_config_pg,omitempty"`
BackupConfigRedis *ManagedDatabaseBackupConfigRedis `json:"backup_config_redis,omitempty"`
NodeCount int `json:"node_count"`
Plan string `json:"plan"`
CoreNumber int `json:"core_number"`
StorageSize int `json:"storage_size"`
MemoryAmount int `json:"memory_amount"`
Zones ManagedDatabaseServicePlanZones `json:"zones"`
// Deprecated: Redis support will be removed in favor of Valkey.
BackupConfigRedis *ManagedDatabaseBackupConfigRedis `json:"backup_config_redis,omitempty"`
BackupConfigValkey *ManagedDatabaseBackupConfigValkey `json:"backup_config_valkey,omitempty"`
NodeCount int `json:"node_count"`
Plan string `json:"plan"`
CoreNumber int `json:"core_number"`
StorageSize int `json:"storage_size"`
MemoryAmount int `json:"memory_amount"`
Zones ManagedDatabaseServicePlanZones `json:"zones"`
}

// Deprecated: ManagedDatabaseBackupConfig is deprecated in favor of service specific ManagedDatabaseBackupConfig<ServiceType> types.
Expand Down Expand Up @@ -793,13 +832,21 @@ type ManagedDatabaseBackupConfigPostgreSQL struct {
RecoveryMode string `json:"recovery_mode"`
}

// Deprecated: Redis support will be removed in favor of Valkey.
// ManagedDatabaseBackupConfigRedis represents backup configuration of a Redis database service plan
type ManagedDatabaseBackupConfigRedis struct {
Interval int `json:"interval"`
MaxCount int `json:"max_count"`
RecoveryMode string `json:"recovery_mode"`
}

// ManagedDatabaseBackupConfigValkey represents backup configuration of a Valkey database service plan
type ManagedDatabaseBackupConfigValkey struct {
Interval int `json:"interval"`
MaxCount int `json:"max_count"`
RecoveryMode string `json:"recovery_mode"`
}

// ManagedDatabaseServicePlanZones is a helper for unmarshaling database plan zones
type ManagedDatabaseServicePlanZones []ManagedDatabaseServicePlanZone

Expand Down Expand Up @@ -843,10 +890,12 @@ type ManagedDatabaseServiceProperty struct {

// ManagedDatabaseMetadata contains additional read-only informational data about the managed database
type ManagedDatabaseMetadata struct {
MaxConnections int `json:"max_connections,omitempty"`
PGVersion string `json:"pg_version,omitempty"`
MySQLVersion string `json:"mysql_version,omitempty"`
MaxConnections int `json:"max_connections,omitempty"`
PGVersion string `json:"pg_version,omitempty"`
MySQLVersion string `json:"mysql_version,omitempty"`
// Deprecated: Redis support will be removed in favor of Valkey.
RedisVersion string `json:"redis_version,omitempty"`
ValkeyVersion string `json:"valkey_version,omitempty"`
WriteBlockThresholdExceeded *bool `json:"write_block_threshold_exceeded,omitempty"`
OpenSearchVersion string `json:"opensearch_version,omitempty"`
UpgradeVersion string `json:"upgrade_version,omitempty"`
Expand Down
2 changes: 2 additions & 0 deletions upcloud/managed_database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ func TestManagedDatabaseMetadata(t *testing.T) {
{
"metadata": {
"redis_version": "7",
"valkey_version": "7",
"mysql_version": "8.0.30",
"pg_version": "14.6",
"write_block_threshold_exceeded": false,
Expand All @@ -692,6 +693,7 @@ func TestManagedDatabaseMetadata(t *testing.T) {
PGVersion: "14.6",
MySQLVersion: "8.0.30",
RedisVersion: "7",
ValkeyVersion: "7",
WriteBlockThresholdExceeded: BoolPtr(false),
},
}
Expand Down
10 changes: 7 additions & 3 deletions upcloud/request/managed_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type CloneManagedDatabaseRequest struct {
// CloneTime selects a point-in-time from where to clone the data. Zero value selects the most recent available.
CloneTime time.Time `json:"clone_time"`

// Only for Redis. Create a clone of your database service data from the backups by name.
// Only for Valkey. Create a clone of your database service data from the backups by name.
BackupName string `json:"backup_name,omitempty"`

HostNamePrefix string `json:"hostname_prefix"`
Expand Down Expand Up @@ -535,7 +535,9 @@ type CreateManagedDatabaseUserRequest struct {
Authentication upcloud.ManagedDatabaseUserAuthenticationType `json:"authentication,omitempty"`
OpenSearchAccessControl *upcloud.ManagedDatabaseUserOpenSearchAccessControl `json:"opensearch_access_control,omitempty"`
PGAccessControl *upcloud.ManagedDatabaseUserPGAccessControl `json:"pg_access_control,omitempty"`
RedisAccessControl *upcloud.ManagedDatabaseUserRedisAccessControl `json:"redis_access_control,omitempty"`
// Deprecated: Redis support will be removed in favor of Valkey.
RedisAccessControl *upcloud.ManagedDatabaseUserRedisAccessControl `json:"redis_access_control,omitempty"` //nolint:staticcheck // To be removed when Redis support has been removed
ValkeyAccessControl *upcloud.ManagedDatabaseUserValkeyAccessControl `json:"valkey_access_control,omitempty"`
}

// RequestURL implements the request.Request interface
Expand Down Expand Up @@ -608,7 +610,9 @@ type ModifyManagedDatabaseUserAccessControlRequest struct {
Username string `json:"-"`
OpenSearchAccessControl *upcloud.ManagedDatabaseUserOpenSearchAccessControl `json:"opensearch_access_control,omitempty"`
PGAccessControl *upcloud.ManagedDatabaseUserPGAccessControl `json:"pg_access_control,omitempty"`
RedisAccessControl *upcloud.ManagedDatabaseUserRedisAccessControl `json:"redis_access_control,omitempty"`
// Deprecated: Redis support will be removed in favor of Valkey.
RedisAccessControl *upcloud.ManagedDatabaseUserRedisAccessControl `json:"redis_access_control,omitempty"` //nolint:staticcheck // To be removed when Redis support has been removed
ValkeyAccessControl *upcloud.ManagedDatabaseUserValkeyAccessControl `json:"valkey_access_control,omitempty"`
}

// RequestURL implements the request.Request interface
Expand Down
8 changes: 4 additions & 4 deletions upcloud/request/managed_database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ func TestCreateManagedDatabaseUserRequest(t *testing.T) {
"username": "api-doc-user",
"password": "new-password",
"authentication": "caching_sha2_password",
"redis_access_control": {
"valkey_access_control": {
"categories": ["+@set"],
"channels": ["*"],
"commands": ["+set"],
Expand All @@ -444,7 +444,7 @@ func TestCreateManagedDatabaseUserRequest(t *testing.T) {
PGAccessControl: &upcloud.ManagedDatabaseUserPGAccessControl{
AllowReplication: upcloud.BoolPtr(true),
},
RedisAccessControl: &upcloud.ManagedDatabaseUserRedisAccessControl{
ValkeyAccessControl: &upcloud.ManagedDatabaseUserValkeyAccessControl{
Categories: &[]string{"+@set"},
Channels: &[]string{"*"},
Commands: &[]string{"+set"},
Expand Down Expand Up @@ -473,7 +473,7 @@ func TestCreateManagedDatabaseUserRequest(t *testing.T) {
func TestModifyManagedDatabaseUserAccessControlRequest(t *testing.T) {
want := `
{
"redis_access_control": {
"valkey_access_control": {
"categories": ["+@set"],
"channels": ["*"],
"commands": ["+set"],
Expand All @@ -490,7 +490,7 @@ func TestModifyManagedDatabaseUserAccessControlRequest(t *testing.T) {
PGAccessControl: &upcloud.ManagedDatabaseUserPGAccessControl{
AllowReplication: upcloud.BoolPtr(true),
},
RedisAccessControl: &upcloud.ManagedDatabaseUserRedisAccessControl{
ValkeyAccessControl: &upcloud.ManagedDatabaseUserValkeyAccessControl{
Categories: &[]string{"+@set"},
Channels: &[]string{"*"},
Commands: &[]string{"+set"},
Expand Down
Loading

0 comments on commit a8a0094

Please sign in to comment.