Skip to content

Commit

Permalink
Merge pull request #21 from Rey-Lane/add_datastore_backups
Browse files Browse the repository at this point in the history
Add datastore backups
  • Loading branch information
Gogen120 authored Jun 21, 2023
2 parents 501eb8a + 96e800b commit a9c3d84
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 29 deletions.
91 changes: 64 additions & 27 deletions datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,37 +41,40 @@ type Firewall struct {

// Datastore is the API response for the datastores.
type Datastore struct {
ID string `json:"id"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
ProjectID string `json:"project_id"`
Name string `json:"name"`
TypeID string `json:"type_id"`
SubnetID string `json:"subnet_id"`
FlavorID string `json:"flavor_id"`
Status Status `json:"status"`
Connection map[string]string `json:"connection"`
Firewall []Firewall `json:"firewall"`
Instances []Instances `json:"instances"`
Config map[string]interface{} `json:"config"`
Pooler Pooler `json:"pooler"`
Flavor Flavor `json:"flavor"`
NodeCount int `json:"node_count"`
Enabled bool `json:"enabled"`
ID string `json:"id"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
ProjectID string `json:"project_id"`
Name string `json:"name"`
TypeID string `json:"type_id"`
SubnetID string `json:"subnet_id"`
FlavorID string `json:"flavor_id"`
Status Status `json:"status"`
Connection map[string]string `json:"connection"`
Firewall []Firewall `json:"firewall"`
Instances []Instances `json:"instances"`
Config map[string]interface{} `json:"config"`
Pooler Pooler `json:"pooler"`
Flavor Flavor `json:"flavor"`
NodeCount int `json:"node_count"`
Enabled bool `json:"enabled"`
IsMaintenance bool `json:"is_maintenance"`
BackupRetentionDays int `json:"backup_retention_days"`
}

// DatastoreCreateOpts represents options for the datastore Create request.
type DatastoreCreateOpts struct {
Flavor *Flavor `json:"flavor,omitempty"`
Restore *Restore `json:"restore,omitempty"`
Pooler *Pooler `json:"pooler,omitempty"`
Config map[string]interface{} `json:"config,omitempty"`
Name string `json:"name"`
TypeID string `json:"type_id"`
SubnetID string `json:"subnet_id"`
FlavorID string `json:"flavor_id,omitempty"`
RedisPassword string `json:"redis_password,omitempty"`
NodeCount int `json:"node_count"`
Flavor *Flavor `json:"flavor,omitempty"`
Restore *Restore `json:"restore,omitempty"`
Pooler *Pooler `json:"pooler,omitempty"`
Config map[string]interface{} `json:"config,omitempty"`
Name string `json:"name"`
TypeID string `json:"type_id"`
SubnetID string `json:"subnet_id"`
FlavorID string `json:"flavor_id,omitempty"`
RedisPassword string `json:"redis_password,omitempty"`
NodeCount int `json:"node_count"`
BackupRetentionDays int `json:"backup_retention_days,omitempty"`
}

// DatastoreUpdateOpts represents options for the datastore Update request.
Expand Down Expand Up @@ -119,6 +122,11 @@ type DatastoreQueryParams struct {
Deleted bool `json:"deleted,omitempty"`
}

// DatastoreBackupsOpts represents update options for the Datastore backups.
type DatastoreBackupsOpts struct {
BackupRetentionDays int `json:"backup_retention_days"`
}

// Datastores returns all datastores.
func (api *API) Datastores(ctx context.Context, params *DatastoreQueryParams) ([]Datastore, error) {
uri, err := setQueryParams("/datastores", params)
Expand Down Expand Up @@ -374,3 +382,32 @@ func (api *API) PasswordDatastore(ctx context.Context, datastoreID string, opts

return result.Datastore, nil
}

// BackupsDatastore updates backups parameters of an existing datastore.
func (api *API) BackupsDatastore(ctx context.Context, datastoreID string, opts DatastoreBackupsOpts) (Datastore, error) { //nolint
uri := fmt.Sprintf("/datastores/%s/backups", datastoreID)
backupsDatastoreOpts := struct {
Datastore DatastoreBackupsOpts `json:"backups"`
}{
Datastore: opts,
}
requestBody, err := json.Marshal(backupsDatastoreOpts)
if err != nil {
return Datastore{}, fmt.Errorf("Error marshalling params to JSON, %w", err)
}

resp, err := api.makeRequest(ctx, http.MethodPut, uri, requestBody)
if err != nil {
return Datastore{}, err
}

var result struct {
Datastore Datastore `json:"datastore"`
}
err = json.Unmarshal(resp, &result)
if err != nil {
return Datastore{}, fmt.Errorf("Error during Unmarshal, %w", err)
}

return result.Datastore, nil
}
36 changes: 34 additions & 2 deletions datastore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ func TestCreateDatatastoreInvalidTypeID(t *testing.T) {
expected := &DBaaSAPIError{}
expected.APIError.Code = 400
expected.APIError.Title = ErrorBadRequestTitle
expected.APIError.Message = `Validation failure:
expected.APIError.Message = `Validation failure:
{'datastore.type_id': \"'20d7bcf4-f8d6-4bf6-b8f6-46cb440a87f' is not a 'UUID'\"}`

createDatastoreOpts := DatastoreCreateOpts{
Expand Down Expand Up @@ -968,7 +968,7 @@ func TestPoolerDatatastoreInvalidMode(t *testing.T) {
expected := &DBaaSAPIError{}
expected.APIError.Code = 400
expected.APIError.Title = ErrorBadRequestTitle
expected.APIError.Message = `Validation failure:
expected.APIError.Message = `Validation failure:
{'pooler.mode': \"'abc' is not one of ['session', 'transaction', 'statement']\"}`

poolerDatastoreOpts := DatastorePoolerOpts{
Expand Down Expand Up @@ -1084,3 +1084,35 @@ func TestPasswordDatastore(t *testing.T) {
assert.Equal(t, datastoreUpdateExpected, actual)
}
}

func TestBackupsDatastore(t *testing.T) {
httpmock.Activate()
testClient := SetupTestClient()
defer httpmock.DeactivateAndReset()

httpmock.RegisterResponder("PUT", testClient.Endpoint+"/datastores/"+datastoreID+"/backups",
func(req *http.Request) (*http.Response, error) {
if err := json.NewDecoder(req.Body).Decode(&DatastoreBackupsOpts{}); err != nil {
return httpmock.NewStringResponse(400, ""), err
}

datastores := make(map[string]Datastore)
datastores["datastore"] = datastoreUpdateResponse

resp, err := httpmock.NewJsonResponse(200, datastores)
if err != nil {
return httpmock.NewStringResponse(500, ""), err
}
return resp, nil
})

backupsDatastoreOpts := DatastoreBackupsOpts{
BackupRetentionDays: 14,
}

actual, err := testClient.BackupsDatastore(context.Background(), datastoreID, backupsDatastoreOpts)
if assert.NoError(t, err) {
assert.Equal(t, httpmock.GetTotalCallCount(), 1)
assert.Equal(t, datastoreUpdateExpected, actual)
}
}

0 comments on commit a9c3d84

Please sign in to comment.