Skip to content

Commit d9d8d7c

Browse files
Merge pull request #213 from RedisLabs/feat/OPCR-18-upgrade-redis-endpoint
OPCR-18 upgrade redis endpoint
2 parents 6b33120 + 01740b6 commit d9d8d7c

File tree

8 files changed

+268
-145
lines changed

8 files changed

+268
-145
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22
All notable changes to this project will be documented in this file.
33
See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/).
44

5+
## 0.33.0
6+
7+
### Added:
8+
* Adding Upgrade Redis database endpoint
9+
* Adding Get Redis versions for subscription endpoint
10+
11+
## 0.32.0
12+
13+
### Added
14+
15+
* Adding redisVersion support on the create, get and list endpoints for pro databases.
16+
517
## 0.31.0
618

719
### Added

database_test.go

Lines changed: 109 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package rediscloud_api
33
import (
44
"context"
55
"fmt"
6+
"net/http"
67
"net/http/httptest"
78
"testing"
89
"time"
@@ -339,67 +340,51 @@ func TestDatabase_Get_wraps404Error(t *testing.T) {
339340
}
340341

341342
func TestDatabase_Update(t *testing.T) {
342-
s := httptest.NewServer(testServer("key", "secret", putRequest(t, "/subscriptions/42/databases/18", `{
343-
"dryRun": false,
344-
"name": "example",
345-
"datasetSizeInGb": 1,
346-
"supportOSSClusterApi": false,
347-
"respVersion": "resp3",
348-
"useExternalEndpointForOSSClusterApi": false,
349-
"dataEvictionPolicy": "allkeys-lru",
350-
"replication": true,
351-
"throughputMeasurement": {
352-
"by": "operations-per-second",
353-
"value": 1000
354-
},
355-
"regexRules": [".*"],
356-
"dataPersistence": "none",
357-
"replicaOf": [
358-
"another"
359-
],
360-
"periodicBackupPath": "s3://bucket-name",
361-
"sourceIp": [
362-
"10.0.0.1"
363-
],
364-
"clientSslCertificate": "something",
365-
"clientTlsCertificates": ["something", "new"],
366-
"enableTls": false,
367-
"password": "fooBar",
368-
"alerts": [
369-
{
370-
"name": "dataset-size",
371-
"value": 80
372-
}
373-
],
374-
"enableDefaultUser": false,
375-
"queryPerformanceFactor": "2x"
376-
}`, `{
377-
"taskId": "task",
378-
"commandType": "databaseUpdateRequest",
379-
"status": "received",
380-
"description": "Task request received and is being queued for processing.",
381-
"timestamp": "2020-11-02T09:05:34.3Z",
382-
"_links": {
383-
"task": {
384-
"href": "https://example.org",
385-
"title": "getTaskStatusUpdates",
386-
"type": "GET"
387-
}
388-
}
389-
}`), getRequest(t, "/tasks/task", `{
390-
"taskId": "task",
391-
"commandType": "databaseUpdateRequest",
392-
"status": "processing-completed",
393-
"timestamp": "2020-10-28T09:58:16.798Z",
394-
"response": {
395-
},
396-
"_links": {
397-
"self": {
398-
"href": "https://example.com",
399-
"type": "GET"
400-
}
401-
}
402-
}`)))
343+
flow := taskFlow(
344+
t,
345+
http.MethodPut,
346+
"/subscriptions/42/databases/18",
347+
`{
348+
"dryRun": false,
349+
"name": "example",
350+
"datasetSizeInGb": 1,
351+
"supportOSSClusterApi": false,
352+
"respVersion": "resp3",
353+
"useExternalEndpointForOSSClusterApi": false,
354+
"dataEvictionPolicy": "allkeys-lru",
355+
"replication": true,
356+
"throughputMeasurement": {
357+
"by": "operations-per-second",
358+
"value": 1000
359+
},
360+
"regexRules": [".*"],
361+
"dataPersistence": "none",
362+
"replicaOf": [
363+
"another"
364+
],
365+
"periodicBackupPath": "s3://bucket-name",
366+
"sourceIp": [
367+
"10.0.0.1"
368+
],
369+
"clientSslCertificate": "something",
370+
"clientTlsCertificates": ["something", "new"],
371+
"enableTls": false,
372+
"password": "fooBar",
373+
"alerts": [
374+
{
375+
"name": "dataset-size",
376+
"value": 80
377+
}
378+
],
379+
"enableDefaultUser": false,
380+
"queryPerformanceFactor": "2x"
381+
}`,
382+
"task",
383+
"databaseUpdateRequest",
384+
)
385+
386+
s := httptest.NewServer(testServer("key", "secret", flow...))
387+
defer s.Close()
403388

404389
subject, err := clientFromTestServer(s, "key", "secret")
405390
require.NoError(t, err)
@@ -439,33 +424,17 @@ func TestDatabase_Update(t *testing.T) {
439424
}
440425

441426
func TestDatabase_Delete(t *testing.T) {
442-
s := httptest.NewServer(testServer("key", "secret", deleteRequest(t, "/subscriptions/42/databases/4291", `{
443-
"taskId": "task",
444-
"commandType": "databaseDeleteRequest",
445-
"status": "received",
446-
"description": "Task request received and is being queued for processing.",
447-
"timestamp": "2020-11-02T09:05:34.3Z",
448-
"_links": {
449-
"task": {
450-
"href": "https://example.org",
451-
"title": "getTaskStatusUpdates",
452-
"type": "GET"
453-
}
454-
}
455-
}`), getRequest(t, "/tasks/task", `{
456-
"taskId": "e02b40d6-1395-4861-a3b9-ecf829d835fd",
457-
"commandType": "databaseDeleteRequest",
458-
"status": "processing-completed",
459-
"timestamp": "2020-10-28T09:58:16.798Z",
460-
"response": {
461-
},
462-
"_links": {
463-
"self": {
464-
"href": "https://example.com",
465-
"type": "GET"
466-
}
467-
}
468-
}`)))
427+
flow := taskFlow(
428+
t,
429+
http.MethodDelete,
430+
"/subscriptions/42/databases/4291",
431+
"",
432+
"task",
433+
"databaseDeleteRequest",
434+
)
435+
436+
s := httptest.NewServer(testServer("key", "secret", flow...))
437+
defer s.Close()
469438

470439
subject, err := clientFromTestServer(s, "key", "secret")
471440
require.NoError(t, err)
@@ -475,33 +444,17 @@ func TestDatabase_Delete(t *testing.T) {
475444
}
476445

477446
func TestDatabase_Backup(t *testing.T) {
478-
s := httptest.NewServer(testServer("key", "secret", postRequestWithNoRequest(t, "/subscriptions/42/databases/18/backup", `{
479-
"taskId": "task-uuid",
480-
"commandType": "databaseBackupRequest",
481-
"status": "received",
482-
"description": "Task request received and is being queued for processing.",
483-
"timestamp": "2020-11-02T09:05:34.3Z",
484-
"_links": {
485-
"task": {
486-
"href": "https://example.org",
487-
"title": "getTaskStatusUpdates",
488-
"type": "GET"
489-
}
490-
}
491-
}`), getRequest(t, "/tasks/task-uuid", `{
492-
"taskId": "task-uuid",
493-
"commandType": "databaseBackupRequest",
494-
"status": "processing-completed",
495-
"timestamp": "2020-10-28T09:58:16.798Z",
496-
"response": {
497-
},
498-
"_links": {
499-
"self": {
500-
"href": "https://example.com",
501-
"type": "GET"
502-
}
503-
}
504-
}`)))
447+
flow := taskFlow(
448+
t,
449+
http.MethodPost,
450+
"/subscriptions/42/databases/18/backup",
451+
"",
452+
"task-uuid",
453+
"databaseBackupRequest",
454+
)
455+
456+
s := httptest.NewServer(testServer("key", "secret", flow...))
457+
defer s.Close()
505458

506459
subject, err := clientFromTestServer(s, "key", "secret")
507460
require.NoError(t, err)
@@ -511,36 +464,20 @@ func TestDatabase_Backup(t *testing.T) {
511464
}
512465

513466
func TestDatabase_Import(t *testing.T) {
514-
s := httptest.NewServer(testServer("key", "secret", postRequest(t, "/subscriptions/42/databases/81/import", `{
515-
"sourceType": "magic",
516-
"importFromUri": ["tinkerbell"]
517-
}`, `{
518-
"taskId": "task-uuid",
519-
"commandType": "databaseImportRequest",
520-
"status": "received",
521-
"description": "Task request received and is being queued for processing.",
522-
"timestamp": "2020-11-02T09:05:34.3Z",
523-
"_links": {
524-
"task": {
525-
"href": "https://example.org",
526-
"title": "getTaskStatusUpdates",
527-
"type": "GET"
528-
}
529-
}
530-
}`), getRequest(t, "/tasks/task-uuid", `{
531-
"taskId": "task-uuid",
532-
"commandType": "databaseImportRequest",
533-
"status": "processing-completed",
534-
"timestamp": "2020-10-28T09:58:16.798Z",
535-
"response": {
536-
},
537-
"_links": {
538-
"self": {
539-
"href": "https://example.com",
540-
"type": "GET"
541-
}
542-
}
543-
}`)))
467+
flow := taskFlow(
468+
t,
469+
http.MethodPost,
470+
"/subscriptions/42/databases/81/import",
471+
`{
472+
"sourceType": "magic",
473+
"importFromUri": ["tinkerbell"]
474+
}`,
475+
"task-uuid",
476+
"databaseImportRequest",
477+
)
478+
479+
s := httptest.NewServer(testServer("key", "secret", flow...))
480+
defer s.Close()
544481

545482
subject, err := clientFromTestServer(s, "key", "secret")
546483
require.NoError(t, err)
@@ -567,3 +504,30 @@ func TestDatabase_Certificate(t *testing.T) {
567504
}, certificate)
568505

569506
}
507+
508+
func TestDatabase_UpgradeRedisVersion(t *testing.T) {
509+
flow := taskFlow(
510+
t,
511+
http.MethodPost,
512+
"/subscriptions/42/databases/18/upgrade",
513+
`{ "targetRedisVersion": "7.2" }`,
514+
"upgrade-task-id",
515+
"databaseUpgradeRequest",
516+
)
517+
518+
s := httptest.NewServer(testServer("key", "secret", flow...))
519+
defer s.Close()
520+
521+
subject, err := clientFromTestServer(s, "key", "secret")
522+
require.NoError(t, err)
523+
524+
err = subject.Database.UpgradeRedisVersion(
525+
context.TODO(),
526+
42,
527+
18,
528+
databases.UpgradeRedisVersion{
529+
TargetRedisVersion: redis.String("7.2"),
530+
},
531+
)
532+
require.NoError(t, err)
533+
}

service/databases/model.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,14 @@ type Import struct {
198198
ImportFromURI []*string `json:"importFromUri,omitempty"`
199199
}
200200

201+
type UpgradeRedisVersion struct {
202+
TargetRedisVersion *string `json:"targetRedisVersion,omitempty"`
203+
}
204+
205+
func (o UpgradeRedisVersion) String() string {
206+
return internal.ToString(o)
207+
}
208+
201209
func (o Import) String() string {
202210
return internal.ToString(o)
203211
}

service/databases/service.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ func (a *API) Update(ctx context.Context, subscription int, database int, update
8686
return a.taskWaiter.Wait(ctx, *task.ID)
8787
}
8888

89+
// UpgradeRedisVersion will upgrade the Redis version of an existing database.
90+
func (a *API) UpgradeRedisVersion(ctx context.Context, subscription int, database int, upgradeVersion UpgradeRedisVersion) error {
91+
var task internal.TaskResponse
92+
err := a.client.Post(ctx, fmt.Sprintf("upgrade database %d version for subscription %d", database, subscription), fmt.Sprintf("/subscriptions/%d/databases/%d/upgrade", subscription, database), upgradeVersion, &task)
93+
if err != nil {
94+
return err
95+
}
96+
97+
a.logger.Printf("Waiting for database %d for subscription %d to finish being upgraded", database, subscription)
98+
99+
return a.taskWaiter.Wait(ctx, *task.ID)
100+
}
101+
89102
// Delete will destroy an existing database.
90103
func (a *API) Delete(ctx context.Context, subscription int, database int) error {
91104
var task internal.TaskResponse

service/subscriptions/model.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,17 @@ type ActiveActiveDatabase struct {
320320
WriteOperationsPerSecond *int `json:"writeOperationsPerSecond,omitempty"`
321321
}
322322

323+
type RedisVersion struct {
324+
Version *string `json:"version,omitempty"`
325+
EolDate *string `json:"eolDate,omitempty"`
326+
IsPreview *bool `json:"isPreview,omitempty"`
327+
IsDefault *bool `json:"isDefault,omitempty"`
328+
}
329+
330+
type RedisVersions struct {
331+
RedisVersions []*RedisVersion `json:"redisVersions,omitempty"`
332+
}
333+
323334
type NotFound struct {
324335
ID int
325336
}

service/subscriptions/service.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,25 @@ func (a *API) ListActiveActiveRegions(ctx context.Context, subscription int) ([]
267267
return response.Regions, nil
268268
}
269269

270+
// GetRedisVersions retrieves the Redis database versions available for this subscription.
271+
func (a *API) GetRedisVersions(ctx context.Context, subscription int) (*RedisVersions, error) {
272+
var redisVersions RedisVersions
273+
getRedisVersionsUrl := "/subscriptions/redis-versions?subscriptionId=%d"
274+
275+
path := fmt.Sprintf(getRedisVersionsUrl, subscription)
276+
err := a.client.Get(
277+
ctx,
278+
fmt.Sprintf("get versions for subscription %d", subscription),
279+
path,
280+
&redisVersions,
281+
)
282+
283+
if err != nil {
284+
return nil, wrap404Error(subscription, err)
285+
}
286+
return &redisVersions, nil
287+
}
288+
270289
func wrap404Error(id int, err error) error {
271290
if v, ok := err.(*internal.HTTPError); ok && v.StatusCode == http.StatusNotFound {
272291
return &NotFound{ID: id}

0 commit comments

Comments
 (0)