Skip to content

Commit

Permalink
Fix name getting set to empty on updates
Browse files Browse the repository at this point in the history
The name field was getting set to empty on changes to ha replicas. This fixes the issue by using the previous known state for the name field on updates.
  • Loading branch information
aaronblevy committed Jan 8, 2024
1 parent 9bc78bb commit 4b004b9
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 77 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0
github.com/hashicorp/terraform-plugin-testing v1.2.0
github.com/stretchr/testify v1.7.2
)

require (
Expand All @@ -23,6 +24,7 @@ require (
github.com/armon/go-radix v1.0.0 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.6.0 // indirect
Expand Down Expand Up @@ -55,6 +57,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/russross/blackfriday v1.6.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
Expand All @@ -72,4 +75,5 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
79 changes: 79 additions & 0 deletions internal/provider/provider_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package provider

import (
"fmt"
"os"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/stretchr/testify/require"
)

const (
Expand Down Expand Up @@ -41,6 +44,7 @@ var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServe
}

type Config struct {
ResourceName string
Name string
Timeouts Timeouts
MilliCPU int64
Expand All @@ -50,6 +54,81 @@ type Config struct {
VpcID int64
}

func (c *Config) WithName(name string) *Config {
c.Name = name
return c
}

func (c *Config) WithSpec(milliCPU, memoryGB int64) *Config {
c.MilliCPU = milliCPU
c.MemoryGB = memoryGB
return c
}

func (c *Config) WithVPC(ID int64) *Config {
c.VpcID = ID
return c
}

func (c *Config) WithHAReplica(enableHAReplica bool) *Config {
c.EnableHAReplica = enableHAReplica
return c
}

func (c *Config) String(t *testing.T) string {
c.setDefaults()
b := &strings.Builder{}
write := func(format string, a ...any) {
_, err := fmt.Fprintf(b, format, a...)
require.NoError(t, err)
}
_, err := fmt.Fprintf(b, "\n\n resource timescale_service %q { \n", c.ResourceName)
require.NoError(t, err)
if c.Name != "" {
write("name = %q \n", c.Name)
}
if c.EnableHAReplica {
write("enable_ha_replica = %t \n", c.EnableHAReplica)
}
if c.RegionCode != "" {
write("region_code = %q \n", c.RegionCode)
}
if c.VpcID != 0 {
write("vpc_id = %d \n", c.VpcID)
}
write(`
milli_cpu = %d
memory_gb = %d
timeouts = {
create = %q
}`+"\n",
c.MilliCPU, c.MemoryGB, c.Timeouts.Create)
write("}")
return b.String()
}

func (c *Config) setDefaults() {
if c.MilliCPU == 0 {
c.MilliCPU = 500
}
if c.MemoryGB == 0 {
c.MemoryGB = 2
}
if c.Timeouts.Create == "" {
c.Timeouts.Create = "10m"
}
}

// getConfig returns a configuration for a test step
func getConfig(t *testing.T, cfgs ...*Config) string {
res := strings.Builder{}
res.WriteString(providerConfig)
for _, cfg := range cfgs {
res.WriteString(cfg.String(t))
}
return res.String()
}

type Timeouts struct {
Create string
}
Expand Down
3 changes: 3 additions & 0 deletions internal/provider/service_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ The change has been taken into account but must still be propagated. You can run
Optional: true,
// If the name attribute is absent, the provider will generate a default.
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"milli_cpu": schema.Int64Attribute{
MarkdownDescription: "Milli CPU",
Expand Down
92 changes: 15 additions & 77 deletions internal/provider/service_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@ import (
const DEFAULT_VPC_ID = 2074 // Default vpc id for test acc

func TestServiceResource_Default_Success(t *testing.T) {
// Test resource creation succeeds and update is not allowed
// Test resource creation succeeds
config := &Config{
ResourceName: "resource",
}
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
PreCheck: func() { testAccPreCheck(t) },
Steps: []resource.TestStep{
// Create default and Read testing
{
Config: newServiceConfig(Config{
Name: "service resource test init",
}),
Config: getConfig(t, config),
Check: resource.ComposeAggregateTestCheckFunc(
// Verify the name is set.
resource.TestCheckResourceAttr("timescale_service.resource", "name", "service resource test init"),
resource.TestCheckResourceAttrSet("timescale_service.resource", "name"),
// Verify ID value is set in state.
resource.TestCheckResourceAttrSet("timescale_service.resource", "id"),
resource.TestCheckResourceAttrSet("timescale_service.resource", "password"),
Expand All @@ -39,47 +40,31 @@ func TestServiceResource_Default_Success(t *testing.T) {
resource.TestCheckNoResourceAttr("timescale_service.resource", "vpc_id"),
),
},
// Update service name
// Do a compute resize
{
Config: newServiceConfig(Config{
Name: "service resource test update",
}),
Config: getConfig(t, config.WithSpec(1000, 4)),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("timescale_service.resource", "name", "service resource test update"),
resource.TestCheckResourceAttr("timescale_service.resource", "milli_cpu", "1000"),
resource.TestCheckResourceAttr("timescale_service.resource", "memory_gb", "4"),
),
},
// Do a compute resize
// Update service name
{
Config: newServiceComputeResizeConfig(Config{
Name: "service resource test update",
MilliCPU: 1000,
MemoryGB: 4,
}),
Config: getConfig(t, config.WithName("service resource test update")),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("timescale_service.resource", "milli_cpu", "1000"),
resource.TestCheckResourceAttr("timescale_service.resource", "memory_gb", "4"),
resource.TestCheckResourceAttr("timescale_service.resource", "name", "service resource test update"),
),
},
// Add VPC
{
Config: newServiceAddVpc(Config{
Name: "service resource test update",
VpcID: DEFAULT_VPC_ID,
MilliCPU: 1000,
MemoryGB: 4,
}),
Config: getConfig(t, config.WithVPC(DEFAULT_VPC_ID)),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("timescale_service.resource", "vpc_id", "2074"),
),
},
// Add HA replica and remove VPC
{
Config: newServiceAddHAReplica(Config{
Name: "service resource test update",
EnableHAReplica: true,
MilliCPU: 1000,
MemoryGB: 4,
}),
Config: getConfig(t, config.WithVPC(0).WithHAReplica(true)),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckNoResourceAttr("timescale_service.resource", "vpc_id"),
resource.TestCheckResourceAttr("timescale_service.resource", "enable_ha_replica", "true"),
Expand Down Expand Up @@ -219,53 +204,6 @@ func newServiceConfig(config Config) string {
}`, config.Name, config.Timeouts.Create)
}

func newServiceComputeResizeConfig(config Config) string {
if config.Timeouts.Create == "" {
config.Timeouts.Create = "10m"
}
return providerConfig + fmt.Sprintf(`
resource "timescale_service" "resource" {
name = %q
milli_cpu = %d
memory_gb = %d
timeouts = {
create = %q
}
}`, config.Name, config.MilliCPU, config.MemoryGB, config.Timeouts.Create)
}

func newServiceAddVpc(config Config) string {
if config.Timeouts.Create == "" {
config.Timeouts.Create = "10m"
}
return providerConfig + fmt.Sprintf(`
resource "timescale_service" "resource" {
name = %q
milli_cpu = %d
memory_gb = %d
vpc_id = %d
timeouts = {
create = %q
}
}`, config.Name, config.MilliCPU, config.MemoryGB, config.VpcID, config.Timeouts.Create)
}

func newServiceAddHAReplica(config Config) string {
if config.Timeouts.Create == "" {
config.Timeouts.Create = "10m"
}
return providerConfig + fmt.Sprintf(`
resource "timescale_service" "resource" {
name = %q
milli_cpu = %d
memory_gb = %d
enable_ha_replica = %t
timeouts = {
create = %q
}
}`, config.Name, config.MilliCPU, config.MemoryGB, config.EnableHAReplica, config.Timeouts.Create)
}

func newServiceCustomConfig(resourceName string, config Config) string {
if config.Timeouts.Create == "" {
config.Timeouts.Create = "30m"
Expand Down

0 comments on commit 4b004b9

Please sign in to comment.