Skip to content

Commit

Permalink
Merge pull request #57 from ClickHouse/state-consistency
Browse files Browse the repository at this point in the history
fix inconsistent state for certain terraform keys as these are optional arguments
  • Loading branch information
Kinzeng authored May 7, 2024
2 parents 3131cc8 + fe2a207 commit 15c021f
Showing 1 changed file with 26 additions and 70 deletions.
96 changes: 26 additions & 70 deletions clickhouse/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ func (r *ServiceResource) Create(ctx context.Context, req resource.CreateRequest

// Map response body to schema and populate Computed attribute values
plan.ID = types.StringValue(s.Id)
err = r.syncServiceState(ctx, &plan)
err = r.syncServiceState(ctx, &plan, true)
if err != nil {
resp.Diagnostics.AddError(
"Error Reading ClickHouse Service",
Expand All @@ -452,7 +452,7 @@ func (r *ServiceResource) Read(ctx context.Context, req resource.ReadRequest, re
return
}

err := r.syncServiceState(ctx, &state)
err := r.syncServiceState(ctx, &state, false)
if err != nil {
resp.Diagnostics.AddError(
"Error Reading ClickHouse Service",
Expand Down Expand Up @@ -768,66 +768,7 @@ func (r *ServiceResource) Update(ctx context.Context, req resource.UpdateRequest
}
}

s, _ := r.client.GetService(serviceId)

// Update resource state with updated items and timestamp
plan.ID = types.StringValue(s.Id)
plan.Name = types.StringValue(s.Name)
plan.CloudProvider = types.StringValue(s.Provider)
plan.Region = types.StringValue(s.Region)
plan.Tier = types.StringValue(s.Tier)

if s.Tier == "production" {
plan.IdleScaling = types.BoolValue(s.IdleScaling)
if !plan.MinTotalMemoryGb.IsNull() {
plan.MinTotalMemoryGb = types.Int64Value(int64(*s.MinTotalMemoryGb))
}
if !plan.MaxTotalMemoryGb.IsNull() {
plan.MaxTotalMemoryGb = types.Int64Value(int64(*s.MaxTotalMemoryGb))
}
if !plan.IdleTimeoutMinutes.IsNull() {
plan.IdleTimeoutMinutes = types.Int64Value(int64(*s.IdleTimeoutMinutes))
}
}

for ipAccessIndex, ipAccess := range s.IpAccessList {
stateIpAccess := IpAccessModel{
Source: types.StringValue(ipAccess.Source),
}

if !plan.IpAccessList[ipAccessIndex].Description.IsNull() {
stateIpAccess.Description = types.StringValue(ipAccess.Description)
}

plan.IpAccessList[ipAccessIndex] = stateIpAccess
}

var values []attr.Value
for _, endpoint := range s.Endpoints {
obj, _ := types.ObjectValue(endpointObjectType.AttrTypes, map[string]attr.Value{
"protocol": types.StringValue(endpoint.Protocol),
"host": types.StringValue(endpoint.Host),
"port": types.Int64Value(int64(endpoint.Port)),
})

values = append(values, obj)
}
plan.Endpoints, _ = types.ListValue(endpointObjectType, values)

plan.LastUpdated = types.StringValue(time.Now().Format(time.RFC850))
plan.IAMRole = types.StringValue(s.IAMRole)

plan.PrivateEndpointConfig, _ = types.ObjectValue(privateEndpointConfigType.AttrTypes, map[string]attr.Value{
"endpoint_service_id": types.StringValue(s.PrivateEndpointConfig.EndpointServiceId),
"private_dns_hostname": types.StringValue(s.PrivateEndpointConfig.PrivateDnsHostname),
})

// default null config value to empty string array
if plan.PrivateEndpointIds.IsNull() {
state.PrivateEndpointIds = createEmptyList(types.StringType)
} else {
state.PrivateEndpointIds, _ = types.ListValueFrom(ctx, types.StringType, s.PrivateEndpointIds)
}
r.syncServiceState(ctx, &plan, true)

diags = resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
Expand Down Expand Up @@ -863,7 +804,7 @@ func (r *ServiceResource) ImportState(ctx context.Context, req resource.ImportSt
}

// syncServiceState fetches the latest state ClickHouse Cloud API and updates the Terraform state.
func (r *ServiceResource) syncServiceState(ctx context.Context, state *ServiceResourceModel) error {
func (r *ServiceResource) syncServiceState(ctx context.Context, state *ServiceResourceModel, updateTimestamp bool) error {
if state.ID.IsNull() {
return errors.New("service ID must be reset to fetch the service")
}
Expand All @@ -881,10 +822,18 @@ func (r *ServiceResource) syncServiceState(ctx context.Context, state *ServiceRe
state.Tier = types.StringValue(service.Tier)

if service.Tier == "production" {
state.IdleScaling = types.BoolValue(service.IdleScaling)
state.MinTotalMemoryGb = types.Int64Value(int64(*service.MinTotalMemoryGb))
state.MaxTotalMemoryGb = types.Int64Value(int64(*service.MaxTotalMemoryGb))
state.IdleTimeoutMinutes = types.Int64Value(int64(*service.IdleTimeoutMinutes))
if !state.IdleScaling.IsNull() {
state.IdleScaling = types.BoolValue(service.IdleScaling)
}
if !state.MinTotalMemoryGb.IsNull() {
state.MinTotalMemoryGb = types.Int64Value(int64(*service.MinTotalMemoryGb))
}
if !state.MaxTotalMemoryGb.IsNull() {
state.MaxTotalMemoryGb = types.Int64Value(int64(*service.MaxTotalMemoryGb))
}
if !state.IdleTimeoutMinutes.IsNull() {
state.IdleTimeoutMinutes = types.Int64Value(int64(*service.IdleTimeoutMinutes))
}
}

ipAccessList := []IpAccessModel{}
Expand Down Expand Up @@ -920,22 +869,29 @@ func (r *ServiceResource) syncServiceState(ctx context.Context, state *ServiceRe
}
state.Endpoints, _ = types.ListValue(endpointObjectType, endpoints)

state.LastUpdated = types.StringValue(time.Now().Format(time.RFC850))
state.IAMRole = types.StringValue(service.IAMRole)

state.PrivateEndpointConfig, _ = types.ObjectValue(privateEndpointConfigType.AttrTypes, map[string]attr.Value{
"endpoint_service_id": types.StringValue(service.PrivateEndpointConfig.EndpointServiceId),
"private_dns_hostname": types.StringValue(service.PrivateEndpointConfig.PrivateDnsHostname),
})

state.EncryptionKey = types.StringValue(service.EncryptionKey)
state.EncryptionAssumedRoleIdentifier = types.StringValue(service.EncryptionAssumedRoleIdentifier)
if !state.EncryptionKey.IsNull() {
state.EncryptionKey = types.StringValue(service.EncryptionKey)
}
if !state.EncryptionAssumedRoleIdentifier.IsNull() {
state.EncryptionAssumedRoleIdentifier = types.StringValue(service.EncryptionAssumedRoleIdentifier)
}

if len(service.PrivateEndpointIds) == 0 {
state.PrivateEndpointIds = createEmptyList(types.StringType)
} else {
state.PrivateEndpointIds, _ = types.ListValueFrom(ctx, types.StringType, service.PrivateEndpointIds)
}

if updateTimestamp {
state.LastUpdated = types.StringValue(time.Now().Format(time.RFC850))
}

return nil
}

0 comments on commit 15c021f

Please sign in to comment.