Onboard MongoDB Flex instance (#86)
* Onboard instance resource * Add options.type as required field * Implement resource unit tests * Implement data source * Implement acc tests * Adjust update acc test * Fix typo * Adjust update unit tests * Adjustments after review * Minor adjustment for uniformity * Adjustments after review
This commit is contained in:
parent
6372434e56
commit
ade77eb544
12 changed files with 2245 additions and 106 deletions
|
|
@ -64,7 +64,7 @@ var flavorTypes = map[string]attr.Type{
|
|||
"ram": basetypes.Int64Type{},
|
||||
}
|
||||
|
||||
// Struct corresponding to DataSourceModel.Storage
|
||||
// Struct corresponding to Model.Storage
|
||||
type storageModel struct {
|
||||
Class types.String `tfsdk:"class"`
|
||||
Size types.Int64 `tfsdk:"size"`
|
||||
|
|
@ -261,8 +261,9 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
|||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
r.loadFlavorId(ctx, &resp.Diagnostics, &model, flavor)
|
||||
if resp.Diagnostics.HasError() {
|
||||
err := loadFlavorId(ctx, r.client, &model, flavor)
|
||||
if err != nil {
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", fmt.Sprintf("Loading flavor ID: %v", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -395,8 +396,9 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
|||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
r.loadFlavorId(ctx, &resp.Diagnostics, &model, flavor)
|
||||
if resp.Diagnostics.HasError() {
|
||||
err := loadFlavorId(ctx, r.client, &model, flavor)
|
||||
if err != nil {
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Loading flavor ID: %v", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -435,7 +437,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
|||
// Map response body to schema
|
||||
err = mapFields(got, &model, flavor, storage)
|
||||
if err != nil {
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error mapping fields in update", err.Error())
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Processing API payload: %v", err))
|
||||
return
|
||||
}
|
||||
diags = resp.State.Set(ctx, model)
|
||||
|
|
@ -524,15 +526,15 @@ func mapFields(resp *postgresflex.InstanceResponse, model *Model, flavor *flavor
|
|||
}
|
||||
aclList, diags = types.ListValue(types.StringType, acl)
|
||||
if diags.HasError() {
|
||||
return fmt.Errorf("failed to map ACL: %w", core.DiagsToError(diags))
|
||||
return fmt.Errorf("mapping ACL: %w", core.DiagsToError(diags))
|
||||
}
|
||||
}
|
||||
|
||||
var flavorValues map[string]attr.Value
|
||||
if instance.Flavor == nil {
|
||||
flavorValues = map[string]attr.Value{
|
||||
"id": types.StringNull(),
|
||||
"description": types.StringNull(),
|
||||
"id": flavor.Id,
|
||||
"description": flavor.Description,
|
||||
"cpu": flavor.CPU,
|
||||
"ram": flavor.RAM,
|
||||
}
|
||||
|
|
@ -540,13 +542,13 @@ func mapFields(resp *postgresflex.InstanceResponse, model *Model, flavor *flavor
|
|||
flavorValues = map[string]attr.Value{
|
||||
"id": types.StringValue(*instance.Flavor.Id),
|
||||
"description": types.StringValue(*instance.Flavor.Description),
|
||||
"cpu": types.Int64Value(int64(*instance.Flavor.Cpu)),
|
||||
"ram": types.Int64Value(int64(*instance.Flavor.Memory)),
|
||||
"cpu": conversion.ToTypeInt64(instance.Flavor.Cpu),
|
||||
"ram": conversion.ToTypeInt64(instance.Flavor.Memory),
|
||||
}
|
||||
}
|
||||
flavorObject, diags := types.ObjectValue(flavorTypes, flavorValues)
|
||||
if diags.HasError() {
|
||||
return fmt.Errorf("failed to create flavor: %w", core.DiagsToError(diags))
|
||||
return fmt.Errorf("creating flavor: %w", core.DiagsToError(diags))
|
||||
}
|
||||
|
||||
var storageValues map[string]attr.Value
|
||||
|
|
@ -558,12 +560,12 @@ func mapFields(resp *postgresflex.InstanceResponse, model *Model, flavor *flavor
|
|||
} else {
|
||||
storageValues = map[string]attr.Value{
|
||||
"class": types.StringValue(*instance.Storage.Class),
|
||||
"size": types.Int64Value(int64(*instance.Storage.Size)),
|
||||
"size": conversion.ToTypeInt64(instance.Storage.Size),
|
||||
}
|
||||
}
|
||||
storageObject, diags := types.ObjectValue(storageTypes, storageValues)
|
||||
if diags.HasError() {
|
||||
return fmt.Errorf("failed to create storage: %w", core.DiagsToError(diags))
|
||||
return fmt.Errorf("creating storage: %w", core.DiagsToError(diags))
|
||||
}
|
||||
|
||||
idParts := []string{
|
||||
|
|
@ -574,29 +576,13 @@ func mapFields(resp *postgresflex.InstanceResponse, model *Model, flavor *flavor
|
|||
strings.Join(idParts, core.Separator),
|
||||
)
|
||||
model.InstanceId = types.StringValue(instanceId)
|
||||
if instance.Name == nil {
|
||||
model.Name = types.StringNull()
|
||||
} else {
|
||||
model.Name = types.StringValue(*instance.Name)
|
||||
}
|
||||
model.Name = types.StringPointerValue(instance.Name)
|
||||
model.ACL = aclList
|
||||
if instance.BackupSchedule == nil {
|
||||
model.BackupSchedule = types.StringNull()
|
||||
} else {
|
||||
model.BackupSchedule = types.StringValue(*instance.BackupSchedule)
|
||||
}
|
||||
model.BackupSchedule = types.StringPointerValue(instance.BackupSchedule)
|
||||
model.Flavor = flavorObject
|
||||
if instance.Replicas == nil {
|
||||
model.Replicas = types.Int64Null()
|
||||
} else {
|
||||
model.Replicas = types.Int64Value(int64(*instance.Replicas))
|
||||
}
|
||||
model.Replicas = conversion.ToTypeInt64(instance.Replicas)
|
||||
model.Storage = storageObject
|
||||
if instance.Version == nil {
|
||||
model.Version = types.StringNull()
|
||||
} else {
|
||||
model.Version = types.StringValue(*instance.Version)
|
||||
}
|
||||
model.Version = types.StringPointerValue(instance.Version)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -660,37 +646,35 @@ func toUpdatePayload(model *Model, acl []string, flavor *flavorModel, storage *s
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (r *instanceResource) loadFlavorId(ctx context.Context, diags *diag.Diagnostics, model *Model, flavor *flavorModel) {
|
||||
type postgresFlexClient interface {
|
||||
GetFlavorsExecute(ctx context.Context, projectId string) (*postgresflex.FlavorsResponse, error)
|
||||
}
|
||||
|
||||
func loadFlavorId(ctx context.Context, client postgresFlexClient, model *Model, flavor *flavorModel) error {
|
||||
if model == nil {
|
||||
diags.AddError("invalid model", "nil model")
|
||||
return
|
||||
return fmt.Errorf("nil model")
|
||||
}
|
||||
if flavor == nil {
|
||||
diags.AddError("invalid flavor", "nil flavor")
|
||||
return
|
||||
return fmt.Errorf("nil flavor")
|
||||
}
|
||||
cpu := conversion.ToPtrInt32(flavor.CPU)
|
||||
if cpu == nil {
|
||||
diags.AddError("invalid flavor", "nil CPU")
|
||||
return
|
||||
return fmt.Errorf("nil CPU")
|
||||
}
|
||||
ram := conversion.ToPtrInt32(flavor.RAM)
|
||||
if ram == nil {
|
||||
diags.AddError("invalid flavor", "nil RAM")
|
||||
return
|
||||
return fmt.Errorf("nil RAM")
|
||||
}
|
||||
|
||||
projectId := model.ProjectId.ValueString()
|
||||
res, err := r.client.GetFlavors(ctx, projectId).Execute()
|
||||
res, err := client.GetFlavorsExecute(ctx, projectId)
|
||||
if err != nil {
|
||||
diags.AddError("failed to list postgresflex flavors", err.Error())
|
||||
return
|
||||
return fmt.Errorf("listing postgresflex flavors: %w", err)
|
||||
}
|
||||
|
||||
avl := ""
|
||||
if res.Flavors == nil {
|
||||
diags.AddError("no flavors", fmt.Sprintf("couldn't find flavors for id %s", flavor.Id.ValueString()))
|
||||
return
|
||||
return fmt.Errorf("finding flavors for project %s", projectId)
|
||||
}
|
||||
for _, f := range *res.Flavors {
|
||||
if f.Id == nil || f.Cpu == nil || f.Memory == nil {
|
||||
|
|
@ -698,12 +682,14 @@ func (r *instanceResource) loadFlavorId(ctx context.Context, diags *diag.Diagnos
|
|||
}
|
||||
if *f.Cpu == *cpu && *f.Memory == *ram {
|
||||
flavor.Id = types.StringValue(*f.Id)
|
||||
flavor.Description = types.StringValue(*f.Description)
|
||||
break
|
||||
}
|
||||
avl = fmt.Sprintf("%s\n- %d CPU, %d GB RAM", avl, *f.Cpu, *f.Cpu)
|
||||
}
|
||||
if flavor.Id.ValueString() == "" {
|
||||
diags.AddError("invalid flavor", fmt.Sprintf("couldn't find flavor.\navailable specs are:%s", avl))
|
||||
return
|
||||
return fmt.Errorf("couldn't find flavor, available specs are:%s", avl)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue