Skip to content

Commit 3bc7a8e

Browse files
authored
Merge pull request #95 from thalassa-cloud/dbaas-backup-objectstore
Dbaas backup objectstore
2 parents 229df98 + 15c1726 commit 3bc7a8e

9 files changed

Lines changed: 776 additions & 0 deletions

File tree

dbaas/dbaas_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,51 @@ func setupTestServer() *httptest.Server {
6969
} else if r.Method == "DELETE" {
7070
w.WriteHeader(http.StatusNoContent)
7171
}
72+
case "/v1/dbaas/object-stores":
73+
if r.Method == "GET" {
74+
w.WriteHeader(http.StatusOK)
75+
w.Write([]byte(`[]`))
76+
} else if r.Method == "POST" {
77+
w.WriteHeader(http.StatusCreated)
78+
w.Write([]byte(`{
79+
"identity": "os-1",
80+
"name": "backup-store",
81+
"description": "",
82+
"createdAt": "2023-01-01T00:00:00Z",
83+
"objectVersion": 1,
84+
"status": "creating",
85+
"deleteProtection": true,
86+
"retentionPolicy": "30d"
87+
}`))
88+
}
89+
case "/v1/dbaas/object-stores/os-1":
90+
if r.Method == "GET" {
91+
w.WriteHeader(http.StatusOK)
92+
w.Write([]byte(`{
93+
"identity": "os-1",
94+
"name": "backup-store",
95+
"description": "",
96+
"createdAt": "2023-01-01T00:00:00Z",
97+
"objectVersion": 1,
98+
"status": "ready",
99+
"deleteProtection": true,
100+
"retentionPolicy": "30d"
101+
}`))
102+
} else if r.Method == "PUT" {
103+
w.WriteHeader(http.StatusOK)
104+
w.Write([]byte(`{
105+
"identity": "os-1",
106+
"name": "backup-store",
107+
"description": "updated",
108+
"createdAt": "2023-01-01T00:00:00Z",
109+
"objectVersion": 2,
110+
"status": "ready",
111+
"deleteProtection": false,
112+
"retentionPolicy": "60d"
113+
}`))
114+
} else if r.Method == "DELETE" {
115+
w.WriteHeader(http.StatusNoContent)
116+
}
72117
default:
73118
w.WriteHeader(http.StatusNotFound)
74119
w.Write([]byte(`{"error": "not found"}`))

dbaas/dbobjectstores.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package dbaas
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/thalassa-cloud/client-go/filters"
8+
"github.com/thalassa-cloud/client-go/pkg/client"
9+
)
10+
11+
const (
12+
DbObjectStoreEndpoint = "/v1/dbaas/object-stores"
13+
)
14+
15+
// ListDbObjectStoresRequest carries query filters for listing DB object stores.
16+
type ListDbObjectStoresRequest struct {
17+
Filters []filters.Filter
18+
}
19+
20+
// ListDbObjectStores lists all DB object stores for the organisation.
21+
func (c *Client) ListDbObjectStores(ctx context.Context, listRequest *ListDbObjectStoresRequest) ([]DbObjectStore, error) {
22+
stores := []DbObjectStore{}
23+
req := c.R().SetResult(&stores)
24+
25+
if listRequest != nil {
26+
for _, filter := range listRequest.Filters {
27+
for k, v := range filter.ToParams() {
28+
req = req.SetQueryParam(k, v)
29+
}
30+
}
31+
}
32+
33+
resp, err := c.Do(ctx, req, client.GET, DbObjectStoreEndpoint)
34+
if err != nil {
35+
return nil, err
36+
}
37+
if err := c.Check(resp); err != nil {
38+
return stores, err
39+
}
40+
return stores, nil
41+
}
42+
43+
// GetDbObjectStore returns a DB object store by identity.
44+
func (c *Client) GetDbObjectStore(ctx context.Context, identity string) (*DbObjectStore, error) {
45+
if identity == "" {
46+
return nil, fmt.Errorf("identity is required")
47+
}
48+
49+
var store *DbObjectStore
50+
req := c.R().SetResult(&store)
51+
resp, err := c.Do(ctx, req, client.GET, fmt.Sprintf("%s/%s", DbObjectStoreEndpoint, identity))
52+
if err != nil {
53+
return nil, err
54+
}
55+
if err := c.Check(resp); err != nil {
56+
return store, err
57+
}
58+
return store, nil
59+
}
60+
61+
// CreateDbObjectStore creates a new DB object store.
62+
func (c *Client) CreateDbObjectStore(ctx context.Context, create CreateDbObjectStoreRequest) (*DbObjectStore, error) {
63+
if create.Name == "" {
64+
return nil, fmt.Errorf("name is required")
65+
}
66+
if create.Region == "" {
67+
return nil, fmt.Errorf("region is required")
68+
}
69+
70+
var store *DbObjectStore
71+
req := c.R().SetBody(create).SetResult(&store)
72+
resp, err := c.Do(ctx, req, client.POST, DbObjectStoreEndpoint)
73+
if err != nil {
74+
return nil, err
75+
}
76+
if err := c.Check(resp); err != nil {
77+
return store, err
78+
}
79+
return store, nil
80+
}
81+
82+
// UpdateDbObjectStore updates an existing DB object store.
83+
func (c *Client) UpdateDbObjectStore(ctx context.Context, identity string, update UpdateDbObjectStoreRequest) (*DbObjectStore, error) {
84+
if identity == "" {
85+
return nil, fmt.Errorf("identity is required")
86+
}
87+
if update.Name == "" {
88+
return nil, fmt.Errorf("name is required")
89+
}
90+
91+
var store *DbObjectStore
92+
req := c.R().SetBody(update).SetResult(&store)
93+
resp, err := c.Do(ctx, req, client.PUT, fmt.Sprintf("%s/%s", DbObjectStoreEndpoint, identity))
94+
if err != nil {
95+
return nil, err
96+
}
97+
if err := c.Check(resp); err != nil {
98+
return store, err
99+
}
100+
return store, nil
101+
}
102+
103+
// DeleteDbObjectStore deletes a DB object store by identity.
104+
func (c *Client) DeleteDbObjectStore(ctx context.Context, identity string) error {
105+
if identity == "" {
106+
return fmt.Errorf("identity is required")
107+
}
108+
109+
req := c.R()
110+
resp, err := c.Do(ctx, req, client.DELETE, fmt.Sprintf("%s/%s", DbObjectStoreEndpoint, identity))
111+
if err != nil {
112+
return err
113+
}
114+
return c.Check(resp)
115+
}

dbaas/dbobjectstores_test.go

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package dbaas
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
"github.com/thalassa-cloud/client-go/pkg/client"
10+
)
11+
12+
func TestListDbObjectStores(t *testing.T) {
13+
server := setupTestServer()
14+
defer server.Close()
15+
16+
c, err := client.NewClient(client.WithBaseURL(server.URL))
17+
require.NoError(t, err)
18+
dbaasClient, err := New(c)
19+
require.NoError(t, err)
20+
21+
stores, err := dbaasClient.ListDbObjectStores(context.Background(), nil)
22+
require.NoError(t, err)
23+
assert.Empty(t, stores)
24+
}
25+
26+
func TestCreateDbObjectStore(t *testing.T) {
27+
server := setupTestServer()
28+
defer server.Close()
29+
30+
c, err := client.NewClient(client.WithBaseURL(server.URL))
31+
require.NoError(t, err)
32+
dbaasClient, err := New(c)
33+
require.NoError(t, err)
34+
35+
tests := []struct {
36+
name string
37+
req CreateDbObjectStoreRequest
38+
expectedError string
39+
}{
40+
{
41+
name: "success",
42+
req: CreateDbObjectStoreRequest{
43+
Name: "backup-store",
44+
Description: "",
45+
Region: "nl-01",
46+
},
47+
},
48+
{
49+
name: "missing name",
50+
req: CreateDbObjectStoreRequest{
51+
Region: "nl-01",
52+
},
53+
expectedError: "name is required",
54+
},
55+
{
56+
name: "missing region",
57+
req: CreateDbObjectStoreRequest{
58+
Name: "backup-store",
59+
},
60+
expectedError: "region is required",
61+
},
62+
}
63+
64+
for _, tt := range tests {
65+
t.Run(tt.name, func(t *testing.T) {
66+
got, err := dbaasClient.CreateDbObjectStore(context.Background(), tt.req)
67+
if tt.expectedError != "" {
68+
assert.Nil(t, got)
69+
assert.EqualError(t, err, tt.expectedError)
70+
return
71+
}
72+
require.NoError(t, err)
73+
require.NotNil(t, got)
74+
assert.Equal(t, "os-1", got.Identity)
75+
assert.Equal(t, "backup-store", got.Name)
76+
})
77+
}
78+
}
79+
80+
func TestGetDbObjectStore(t *testing.T) {
81+
server := setupTestServer()
82+
defer server.Close()
83+
84+
c, err := client.NewClient(client.WithBaseURL(server.URL))
85+
require.NoError(t, err)
86+
dbaasClient, err := New(c)
87+
require.NoError(t, err)
88+
89+
_, err = dbaasClient.GetDbObjectStore(context.Background(), "")
90+
assert.EqualError(t, err, "identity is required")
91+
92+
got, err := dbaasClient.GetDbObjectStore(context.Background(), "os-1")
93+
require.NoError(t, err)
94+
require.NotNil(t, got)
95+
assert.Equal(t, ObjectStatusReady, got.Status)
96+
}
97+
98+
func TestUpdateDbObjectStore(t *testing.T) {
99+
server := setupTestServer()
100+
defer server.Close()
101+
102+
c, err := client.NewClient(client.WithBaseURL(server.URL))
103+
require.NoError(t, err)
104+
dbaasClient, err := New(c)
105+
require.NoError(t, err)
106+
107+
_, err = dbaasClient.UpdateDbObjectStore(context.Background(), "", UpdateDbObjectStoreRequest{Name: "x"})
108+
assert.EqualError(t, err, "identity is required")
109+
110+
_, err = dbaasClient.UpdateDbObjectStore(context.Background(), "os-1", UpdateDbObjectStoreRequest{})
111+
assert.EqualError(t, err, "name is required")
112+
113+
got, err := dbaasClient.UpdateDbObjectStore(context.Background(), "os-1", UpdateDbObjectStoreRequest{
114+
Name: "backup-store",
115+
Description: "updated",
116+
RetentionPolicy: "60d",
117+
DeleteProtection: false,
118+
})
119+
require.NoError(t, err)
120+
require.NotNil(t, got)
121+
assert.Equal(t, "updated", got.Description)
122+
assert.False(t, got.DeleteProtection)
123+
}
124+
125+
func TestDeleteDbObjectStore(t *testing.T) {
126+
server := setupTestServer()
127+
defer server.Close()
128+
129+
c, err := client.NewClient(client.WithBaseURL(server.URL))
130+
require.NoError(t, err)
131+
dbaasClient, err := New(c)
132+
require.NoError(t, err)
133+
134+
err = dbaasClient.DeleteDbObjectStore(context.Background(), "")
135+
assert.EqualError(t, err, "identity is required")
136+
137+
err = dbaasClient.DeleteDbObjectStore(context.Background(), "os-1")
138+
assert.NoError(t, err)
139+
}

0 commit comments

Comments
 (0)