diff --git a/internal/http_client.go b/internal/http_client.go index 6840e04..6d4407d 100644 --- a/internal/http_client.go +++ b/internal/http_client.go @@ -44,6 +44,10 @@ func (c *HttpClient) Delete(ctx context.Context, name, path string, responseBody return c.connection(ctx, http.MethodDelete, name, path, nil, nil, responseBody) } +func (c *HttpClient) DeleteWithQuery(ctx context.Context, name, path string, requestBody interface{}, responseBody interface{}) error { + return c.connection(ctx, http.MethodDelete, name, path, nil, requestBody, responseBody) +} + func (c *HttpClient) connection(ctx context.Context, method, name, path string, query url.Values, requestBody interface{}, responseBody interface{}) error { parsed := new(url.URL) *parsed = *c.baseUrl diff --git a/service/regions/model.go b/service/regions/model.go index 7e3806a..221d1eb 100644 --- a/service/regions/model.go +++ b/service/regions/model.go @@ -16,6 +16,7 @@ func (o Regions) String() string { type Region struct { RegionId *int `json:"regionId,omitempty"` Region *string `json:"region,omitempty"` + RecreateRegion *bool `json:"-"` DeploymentCIDR *string `json:"deploymentCIDR,omitempty"` VpcId *string `json:"vpcId,omitempty"` Databases []*Database `json:"databases,omitempty"` @@ -31,3 +32,32 @@ type Database struct { ReadOperationsPerSecond *int `json:"readOperationsPerSecond,omitempty"` WriteOperationsPerSecond *int `json:"writeOperationsPerSecond,omitempty"` } + +type CreateRegion struct { + Region *string `json:"region,omitempty"` + DeploymentCIDR *string `json:"deploymentCIDR,omitempty"` + DryRun *bool `json:"dryRun,omitempty"` + Databases []*CreateDatabase `json:"databases,omitempty"` +} + +type DeleteRegion struct { + Region *string `json:"region,omitempty"` +} +type DeleteRegions struct { + Regions []*DeleteRegion `json:"regions,omitempty"` +} + +type CreateLocalThroughput struct { + Region *string `json:"region,omitempty"` + WriteOperationsPerSecond *int `json:"writeOperationsPerSecond"` + ReadOperationsPerSecond *int `json:"readOperationsPerSecond"` +} + +type CreateDatabase struct { + Name *string `json:"name,omitempty"` + LocalThroughputMeasurement *CreateLocalThroughput `json:"localThroughputMeasurement,omitempty"` +} + +type taskResponse struct { + ID *string `json:"taskId,omitempty"` +} diff --git a/service/regions/service.go b/service/regions/service.go index d276f64..49ea36a 100644 --- a/service/regions/service.go +++ b/service/regions/service.go @@ -3,6 +3,9 @@ package regions import ( "context" "fmt" + "net/http" + + "github.com/RedisLabs/rediscloud-go-api/internal" ) type Log interface { @@ -13,7 +16,7 @@ type HttpClient interface { Get(ctx context.Context, name, path string, responseBody interface{}) error Post(ctx context.Context, name, path string, requestBody interface{}, responseBody interface{}) error Put(ctx context.Context, name, path string, requestBody interface{}, responseBody interface{}) error - Delete(ctx context.Context, name, path string, responseBody interface{}) error + DeleteWithQuery(ctx context.Context, name, path string, requestBody interface{}, responseBody interface{}) error } type Task interface { @@ -32,6 +35,24 @@ func NewAPI(client HttpClient, task Task, logger Log) *API { return &API{client: client, task: task, logger: logger} } +// Create will create a new subscription. +func (a *API) Create(ctx context.Context, subId int, region CreateRegion) (int, error) { + var task taskResponse + err := a.client.Post(ctx, "create subscription", fmt.Sprintf("/subscriptions/%d/regions", subId), region, &task) + if err != nil { + return 0, err + } + + a.logger.Printf("Waiting for task %s to finish creating the subscription", task) + + id, err := a.task.WaitForResourceId(ctx, *task.ID) + if err != nil { + return 0, err + } + + return id, nil +} + // List will list all of a given subscription's active-active regions. func (a API) List(ctx context.Context, subId int) (*Regions, error) { var response Regions @@ -42,3 +63,35 @@ func (a API) List(ctx context.Context, subId int) (*Regions, error) { return &response, nil } + +func (a *API) DeleteWithQuery(ctx context.Context, id int, regions DeleteRegions) error { + var task taskResponse + err := a.client.DeleteWithQuery(ctx, fmt.Sprintf("delete region %d", id), fmt.Sprintf("/subscriptions/%d/regions/", id), regions, &task) + if err != nil { + return err + } + + a.logger.Printf("Waiting for region %d to finish being deleted", id) + + err = a.task.Wait(ctx, *task.ID) + if err != nil { + return err + } + + return nil +} + +type NotFound struct { + id int +} + +func (f *NotFound) Error() string { + return fmt.Sprintf("subscription %d not found", f.id) +} + +func wrap404Error(id int, err error) error { + if v, ok := err.(*internal.HTTPError); ok && v.StatusCode == http.StatusNotFound { + return &NotFound{id: id} + } + return err +}