Skip to content

Commit

Permalink
Add integration for read replicas
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronblevy committed Jan 10, 2024
1 parent 4b004b9 commit 8c5c314
Show file tree
Hide file tree
Showing 10 changed files with 364 additions and 40 deletions.
1 change: 1 addition & 0 deletions docs/resources/service.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ The change has been taken into account but must still be propagated. You can run
- `memory_gb` (Number) Memory GB
- `milli_cpu` (Number) Milli CPU
- `name` (String) Service Name is the configurable name assigned to this resource. If none is provided, a default will be generated by the provider.
- `read_replica_source` (String) If set, this database will be a read replica of the provided source database. The region must be the same as the source, or if ommitted will be handled by the provider
- `region_code` (String) The region for this service.
- `storage_gb` (Number, Deprecated) Deprecated: Storage GB
- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))
Expand Down
5 changes: 5 additions & 0 deletions examples/resources/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ resource "timescale_service" "test" {
# memory_gb = 4
# region_code = ""
}

# Read replica
resource "timescale_service" "read_replica" {
read_replica_source = timescale_service.test.id
}
2 changes: 2 additions & 0 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ var (
ResizeInstanceMutation string
//go:embed queries/delete_service.graphql
DeleteServiceMutation string
//go:embed queries/get_all_services.graphql
GetAllServicesQuery string
//go:embed queries/get_service.graphql
GetServiceQuery string
//go:embed queries/vpcs.graphql
Expand Down
3 changes: 2 additions & 1 deletion internal/client/queries/create_service.graphql
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
mutation CreateService($projectId: ID!, $name: String!, $type: Type!, $resourceConfig:
ResourceConfig, $regionCode: String!, $vpcId: ID) {
ResourceConfig, $regionCode: String!, $vpcId: ID, $forkConfig: ForkConfig) {
createService(data:{
projectId:$projectId,
name:$name,
type:$type,
resourceConfig:$resourceConfig,
regionCode:$regionCode,
forkConfig:$forkConfig,
vpcId: $vpcId
}){
initialPassword
Expand Down
44 changes: 44 additions & 0 deletions internal/client/queries/get_all_services.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
query GetAllServices($projectId: ID!) {
getAllServices(projectId: $projectId) {
id
projectId
name
type
created
status
replicaStatus
autoscaleSettings {
enabled
}
regionCode
spec {
... on TimescaleDBServiceSpec {
hostname
username
port
defaultDBName
}
}
resources {
id
spec {
... on ResourceNode {
milliCPU
memoryGB
storageGB
}
}
}
created
vpcEndpoint {
host
port
vpcId
}
forkedFromId {
projectId
serviceId
isStandby
}
}
}
5 changes: 5 additions & 0 deletions internal/client/queries/get_service.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,10 @@ query GetService($projectId: ID!, $serviceId: ID!) {
port
vpcId
}
forkedFromId {
projectId
serviceId
isStandby
}
}
}
44 changes: 44 additions & 0 deletions internal/client/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

type Service struct {
ID string `json:"id"`
ProjectID string `json:"projectId"`
Name string `json:"name"`
AutoscaleSettings struct {
Enabled bool `json:"enabled"`
Expand All @@ -23,6 +24,7 @@ type Service struct {
Created string `json:"created"`
ReplicaStatus string `json:"replicaStatus"`
VpcEndpoint *VpcEndpoint `json:"vpcEndpoint"`
ForkSpec *ForkSpec `json:"forkedFromId"`
}

type ServiceSpec struct {
Expand Down Expand Up @@ -52,6 +54,19 @@ type CreateServiceRequest struct {
RegionCode string
ReplicaCount string
VpcID int64
ForkConfig *ForkConfig
}

type ForkConfig struct {
ProjectID string `json:"projectID"`
ServiceID string `json:"serviceID"`
IsStandby bool `json:"isStandby"`
}

type ForkSpec struct {
ProjectID string `json:"projectId"`
ServiceID string `json:"serviceId"`
IsStandby bool `json:"isStandby"`
}

type CreateServiceResponseData struct {
Expand All @@ -67,6 +82,10 @@ type GetServiceResponse struct {
Service Service `json:"getService"`
}

type GetAllServicesResponse struct {
Services []*Service `json:"getAllServices"`
}

type DeleteServiceResponse struct {
Service Service `json:"deleteService"`
}
Expand All @@ -93,6 +112,9 @@ func (c *Client) CreateService(ctx context.Context, request CreateServiceRequest
if request.VpcID > 0 {
variables["vpcId"] = request.VpcID
}
if request.ForkConfig != nil {
variables["forkConfig"] = request.ForkConfig
}

req := map[string]interface{}{
"operationName": "CreateService",
Expand Down Expand Up @@ -220,6 +242,28 @@ func (c *Client) GetService(ctx context.Context, id string) (*Service, error) {
return &resp.Data.Service, nil
}

func (c *Client) GetAllServices(ctx context.Context) ([]*Service, error) {
tflog.Trace(ctx, "Client.GetAllServices")
req := map[string]interface{}{
"operationName": "GetAllServices",
"query": GetAllServicesQuery,
"variables": map[string]string{
"projectId": c.projectID,
},
}
var resp Response[GetAllServicesResponse]
if err := c.do(ctx, req, &resp); err != nil {
return nil, err
}
if len(resp.Errors) > 0 {
return nil, resp.Errors[0]
}
if resp.Data == nil {
return nil, errors.New("no response found")
}
return resp.Data.Services, nil
}

func (c *Client) DeleteService(ctx context.Context, id string) (*Service, error) {
tflog.Trace(ctx, "Client.DeleteService")
req := map[string]interface{}{
Expand Down
25 changes: 17 additions & 8 deletions internal/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,15 @@ var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServe
}

type Config struct {
ResourceName string
Name string
Timeouts Timeouts
MilliCPU int64
MemoryGB int64
RegionCode string
EnableHAReplica bool
VpcID int64
ResourceName string
Name string
Timeouts Timeouts
MilliCPU int64
MemoryGB int64
RegionCode string
EnableHAReplica bool
VpcID int64
ReadReplicaSource string
}

func (c *Config) WithName(name string) *Config {
Expand All @@ -75,6 +76,11 @@ func (c *Config) WithHAReplica(enableHAReplica bool) *Config {
return c
}

func (c *Config) WithReadReplica(source string) *Config {
c.ReadReplicaSource = source
return c
}

func (c *Config) String(t *testing.T) string {
c.setDefaults()
b := &strings.Builder{}
Expand All @@ -87,6 +93,9 @@ func (c *Config) String(t *testing.T) string {
if c.Name != "" {
write("name = %q \n", c.Name)
}
if c.ReadReplicaSource != "" {
write("read_replica_source = %s \n", c.ReadReplicaSource)
}
if c.EnableHAReplica {
write("enable_ha_replica = %t \n", c.EnableHAReplica)
}
Expand Down
Loading

0 comments on commit 8c5c314

Please sign in to comment.