From 2b260687757fc5fe637e58f0c60da9b572d40155 Mon Sep 17 00:00:00 2001 From: Asim Date: Mon, 11 Aug 2025 10:24:24 +0100 Subject: [PATCH 01/42] autonomous vm cluster resource and data source --- .../odb/cloud_autonomous_vm_cluster.go | 866 ++++++++++++++++++ ...cloud_autonomous_vm_cluster_data_source.go | 433 +++++++++ ..._autonomous_vm_cluster_data_source_test.go | 242 +++++ .../odb/cloud_autonomous_vm_cluster_test.go | 533 +++++++++++ internal/service/odb/service_package.go | 21 + internal/service/odb/tags_gen.go | 128 +++ names/data/names_data.hcl | 29 + 7 files changed, 2252 insertions(+) create mode 100644 internal/service/odb/cloud_autonomous_vm_cluster.go create mode 100644 internal/service/odb/cloud_autonomous_vm_cluster_data_source.go create mode 100644 internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go create mode 100644 internal/service/odb/cloud_autonomous_vm_cluster_test.go create mode 100644 internal/service/odb/service_package.go create mode 100644 internal/service/odb/tags_gen.go diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go new file mode 100644 index 000000000000..97fee679bdc9 --- /dev/null +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -0,0 +1,866 @@ +// Copyright © 2025, Oracle and/or its affiliates. All rights reserved. + +package odb + +import ( + "context" + "errors" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/float64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int32planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + "github.com/hashicorp/terraform-provider-aws/internal/enum" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/odb" + odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" + "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/errs" + "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/sweep" + sweepfw "github.com/hashicorp/terraform-provider-aws/internal/sweep/framework" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// Function annotations are used for resource registration to the Provider. DO NOT EDIT. +// @FrameworkResource("aws_odb_cloud_autonomous_vm_cluster", name="Cloud Autonomous Vm Cluster") +// @Tags(identifierAttribute="arn") +func newResourceCloudAutonomousVmCluster(_ context.Context) (resource.ResourceWithConfigure, error) { + r := &resourceCloudAutonomousVmCluster{} + r.SetDefaultCreateTimeout(24 * time.Hour) + r.SetDefaultUpdateTimeout(24 * time.Hour) + r.SetDefaultDeleteTimeout(24 * time.Hour) + + return r, nil +} + +const ( + ResNameCloudAutonomousVmCluster = "Cloud Autonomous Vm Cluster" + NotAvailableValues = "NOT_AVAILABLE" +) + +var ResourceCloudAutonomousVMCluster = newResourceCloudAutonomousVmCluster + +type resourceCloudAutonomousVmCluster struct { + framework.ResourceWithModel[cloudAutonomousVmClusterResourceModel] + framework.WithTimeouts +} + +func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + status := fwtypes.StringEnumType[odbtypes.ResourceStatus]() + licenseModel := fwtypes.StringEnumType[odbtypes.LicenseModel]() + computeModel := fwtypes.StringEnumType[odbtypes.ComputeModel]() + stringLengthBetween1And255Validator := []validator.String{ + stringvalidator.LengthBetween(1, 255), + } + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + names.AttrARN: framework.ARNAttributeComputedOnly(), + names.AttrID: framework.IDAttribute(), + "cloud_exadata_infrastructure_id": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "Exadata infrastructure id. Changing this will force terraform to create new resource.", + }, + "autonomous_data_storage_percentage": schema.Float32Attribute{ + Computed: true, + Description: "The progress of the current operation on the Autonomous VM cluster, as a percentage.", + }, + "autonomous_data_storage_size_in_tbs": schema.Float64Attribute{ + Required: true, + PlanModifiers: []planmodifier.Float64{ + float64planmodifier.RequiresReplace(), + }, + Description: "The data storage size allocated for Autonomous Databases in the Autonomous VM cluster, in TB. Changing this will force terraform to create new resource.", + }, + "available_autonomous_data_storage_size_in_tbs": schema.Float64Attribute{ + Computed: true, + Description: "The available data storage space for Autonomous Databases in the Autonomous VM cluster, in TB.", + }, + "available_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that you can create with the currently available storage.", + }, + "available_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores available for allocation to Autonomous Databases", + }, + "compute_model": schema.StringAttribute{ + CustomType: computeModel, + Computed: true, + Description: "The compute model of the Autonomous VM cluster: ECPU or OCPU.", + }, + "cpu_core_count": schema.Int32Attribute{ + Computed: true, + Description: "The total number of CPU cores in the Autonomous VM cluster.", + }, + "cpu_core_count_per_node": schema.Int32Attribute{ + Required: true, + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + Description: "The number of CPU cores enabled per node in the Autonomous VM cluster.", + }, + "cpu_percentage": schema.Float32Attribute{ + Computed: true, + Description: "The percentage of total CPU cores currently in use in the Autonomous VM cluster.", + }, + "created_at": schema.StringAttribute{ + Computed: true, + Description: "The date and time when the Autonomous VM cluster was created.", + }, + "data_storage_size_in_gbs": schema.Float64Attribute{ + Computed: true, + Description: "The total data storage allocated to the Autonomous VM cluster, in GB.", + }, + "data_storage_size_in_tbs": schema.Float64Attribute{ + Computed: true, + Description: "The total data storage allocated to the Autonomous VM cluster, in TB.", + }, + "odb_node_storage_size_in_gbs": schema.Int32Attribute{ + Computed: true, + Description: " The local node storage allocated to the Autonomous VM cluster, in gigabytes (GB)", + }, + "db_servers": schema.SetAttribute{ + Required: true, + CustomType: fwtypes.SetOfStringType, + ElementType: types.StringType, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.RequiresReplace(), + }, + Description: "The database servers in the Autonomous VM cluster. Changing this will force terraform to create new resource.", + }, + "description": schema.StringAttribute{ + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + stringplanmodifier.UseStateForUnknown(), + }, + Description: "The description of the Autonomous VM cluster.", + }, + "display_name": schema.StringAttribute{ + Required: true, + Validators: stringLengthBetween1And255Validator, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "The display name of the Autonomous VM cluster. Changing this will force terraform to create new resource.", + }, + "domain": schema.StringAttribute{ + Computed: true, + Description: "The domain name of the Autonomous VM cluster.", + }, + "exadata_storage_in_tbs_lowest_scaled_value": schema.Float64Attribute{ + Computed: true, + Description: "The minimum value to which you can scale down the Exadata storage, in TB.", + }, + "hostname": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Description: "The hostname of the Autonomous VM cluster.", + }, + "is_mtls_enabled_vm_cluster": schema.BoolAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + boolplanmodifier.UseStateForUnknown(), + }, + Description: "Indicates whether mutual TLS (mTLS) authentication is enabled for the Autonomous VM cluster. Changing this will force terraform to create new resource. ", + }, + "license_model": schema.StringAttribute{ + CustomType: licenseModel, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + stringplanmodifier.UseStateForUnknown(), + }, + Description: "The license model for the Autonomous VM cluster. Valid values are LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE . Changing this will force terraform to create new resource.", + }, + "max_acds_lowest_scaled_value": schema.Int32Attribute{ + Computed: true, + Description: "The minimum value to which you can scale down the maximum number of Autonomous CDBs.", + }, + "memory_per_oracle_compute_unit_in_gbs": schema.Int32Attribute{ + Required: true, + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + Description: "The amount of memory allocated per Oracle Compute Unit, in GB. Changing this will force terraform to create new resource.", + }, + "memory_size_in_gbs": schema.Int32Attribute{ + Computed: true, + Description: "The total amount of memory allocated to the Autonomous VM cluster, in gigabytes(GB).", + }, + "node_count": schema.Int32Attribute{ + Computed: true, + Description: "The number of database server nodes in the Autonomous VM cluster.", + }, + "non_provisionable_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that can't be provisioned because of resource constraints.", + }, + "oci_resource_anchor_name": schema.StringAttribute{ + Computed: true, + Description: "The name of the OCI resource anchor associated with this Autonomous VM cluster.", + }, + "oci_url": schema.StringAttribute{ + Computed: true, + Description: "The URL for accessing the OCI console page for this Autonomous VM cluster.", + }, + "ocid": schema.StringAttribute{ + Computed: true, + Description: "The Oracle Cloud Identifier (OCID) of the Autonomous VM cluster.", + }, + "odb_network_id": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "The unique identifier of the ODB network associated with this Autonomous VM Cluster. Changing this will force terraform to create new resource.", + }, + "percent_progress": schema.Float32Attribute{ + Computed: true, + Description: `The progress of the current operation on the Autonomous VM cluster, as a percentage.`, + }, + "provisionable_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that can be provisioned in the Autonomous VM cluster.", + }, + "provisioned_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs currently provisioned in the Autonomous VM cluster.", + }, + "provisioned_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPUs provisioned in the Autonomous VM cluster.", + }, + "reclaimable_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores that can be reclaimed from terminated or scaled-down Autonomous Databases.", + }, + "reserved_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores reserved for system operations and redundancy.", + }, + "scan_listener_port_non_tls": schema.Int32Attribute{ + Required: true, + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + Description: "The SCAN listener port for non-TLS (TCP) protocol. The default is 1521. Changing this will force terraform to create new resource.", + }, + "scan_listener_port_tls": schema.Int32Attribute{ + Required: true, + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + Description: "The SCAN listener port for TLS (TCP) protocol. The default is 2484. Changing this will force terraform to create new resource.", + }, + "shape": schema.StringAttribute{ + Computed: true, + Description: "The shape of the Exadata infrastructure for the Autonomous VM cluster.", + }, + "status": schema.StringAttribute{ + CustomType: status, + Computed: true, + Description: "The status of the Autonomous VM cluster. Possible values include CREATING, AVAILABLE , UPDATING , DELETING , DELETED , FAILED ", + }, + "status_reason": schema.StringAttribute{ + Computed: true, + Description: "Additional information about the current status of the Autonomous VM cluster.", + }, + "time_zone": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + stringplanmodifier.UseStateForUnknown(), + }, + Description: "The time zone of the Autonomous VM cluster. Changing this will force terraform to create new resource.", + }, + "total_container_databases": schema.Int32Attribute{ + Required: true, + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + Description: "The total number of Autonomous Container Databases that can be created with the allocated local storage. Changing this will force terraform to create new resource.", + }, + "time_ords_certificate_expires": schema.StringAttribute{ + Computed: true, + }, + "time_database_ssl_certificate_expires": schema.StringAttribute{ + Computed: true, + Description: "The expiration date and time of the database SSL certificate.", + }, + "maintenance_window": schema.ObjectAttribute{ + Required: true, + CustomType: fwtypes.NewObjectTypeOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel](ctx), + PlanModifiers: []planmodifier.Object{ + objectplanmodifier.RequiresReplace(), + }, + Description: "The maintenance window of the Autonomous VM cluster.", + AttributeTypes: map[string]attr.Type{ + "days_of_week": types.SetType{ + ElemType: fwtypes.StringEnumType[odbtypes.DayOfWeekName](), + }, + "hours_of_day": types.SetType{ + ElemType: types.Int32Type, + }, + "lead_time_in_weeks": types.Int32Type, + "months": types.SetType{ + ElemType: fwtypes.StringEnumType[odbtypes.MonthName](), + }, + "preference": fwtypes.StringEnumType[odbtypes.PreferenceType](), + "weeks_of_month": types.SetType{ + ElemType: types.Int32Type, + }, + }, + }, + names.AttrTags: tftags.TagsAttribute(), + names.AttrTagsAll: tftags.TagsAttributeComputedOnly(), + }, + Blocks: map[string]schema.Block{ + names.AttrTimeouts: timeouts.Block(ctx, timeouts.Opts{ + Create: true, + Update: true, + Delete: true, + }), + }, + } +} + +func (r *resourceCloudAutonomousVmCluster) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + conn := r.Meta().ODBClient(ctx) + + var plan cloudAutonomousVmClusterResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + input := odb.CreateCloudAutonomousVmClusterInput{ + ClientToken: aws.String(id.UniqueId()), + Tags: getTagsIn(ctx), + MaintenanceWindow: r.expandMaintenanceWindow(ctx, plan.MaintenanceWindow), + } + resp.Diagnostics.Append(flex.Expand(ctx, plan, &input)...) + if resp.Diagnostics.HasError() { + return + } + + out, err := conn.CreateCloudAutonomousVmCluster(ctx, &input) + if err != nil { + + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionCreating, ResNameCloudAutonomousVmCluster, plan.DisplayName.ValueString(), err), + err.Error(), + ) + return + } + if out == nil || out.CloudAutonomousVmClusterId == nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionCreating, ResNameCloudAutonomousVmCluster, plan.DisplayName.ValueString(), nil), + errors.New("empty output").Error(), + ) + return + } + + createTimeout := r.CreateTimeout(ctx, plan.Timeouts) + createdAVMC, err := waitCloudAutonomousVmClusterCreated(ctx, conn, *out.CloudAutonomousVmClusterId, createTimeout) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionWaitingForCreation, ResNameCloudAutonomousVmCluster, plan.DisplayName.ValueString(), err), + err.Error(), + ) + return + } + plan.CreatedAt = types.StringValue(createdAVMC.CreatedAt.Format(time.RFC3339)) + + if createdAVMC.TimeDatabaseSslCertificateExpires != nil { + plan.TimeDatabaseSslCertificateExpires = types.StringValue(createdAVMC.TimeDatabaseSslCertificateExpires.Format(time.RFC3339)) + } else { + plan.TimeDatabaseSslCertificateExpires = types.StringValue(NotAvailableValues) + } + + if createdAVMC.TimeOrdsCertificateExpires != nil { + plan.TimeOrdsCertificateExpires = types.StringValue(createdAVMC.TimeOrdsCertificateExpires.Format(time.RFC3339)) + } else { + plan.TimeOrdsCertificateExpires = types.StringValue(NotAvailableValues) + } + + if createdAVMC.MaintenanceWindow != nil { + plan.MaintenanceWindow = r.flattenMaintenanceWindow(ctx, createdAVMC.MaintenanceWindow) + } + resp.Diagnostics.Append(flex.Flatten(ctx, createdAVMC, &plan, + flex.WithIgnoredFieldNamesAppend("TimeOrdsCertificateExpires"), + flex.WithIgnoredFieldNamesAppend("TimeDatabaseSslCertificateExpires"))...) + + resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) +} + +func (r *resourceCloudAutonomousVmCluster) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + + conn := r.Meta().ODBClient(ctx) + + var state cloudAutonomousVmClusterResourceModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + out, err := FindCloudAutonomousVmClusterByID(ctx, conn, state.CloudAutonomousVmClusterId.ValueString()) + + if tfresource.NotFound(err) { + resp.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err)) + resp.State.RemoveResource(ctx) + return + } + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionReading, ResNameCloudAutonomousVmCluster, state.DisplayName.ValueString(), err), + err.Error(), + ) + return + } + + state.CreatedAt = types.StringValue(out.CreatedAt.Format(time.RFC3339)) + if out.TimeOrdsCertificateExpires != nil { + state.TimeOrdsCertificateExpires = types.StringValue(out.TimeOrdsCertificateExpires.Format(time.RFC3339)) + } else { + state.TimeOrdsCertificateExpires = types.StringValue(NotAvailableValues) + } + if out.TimeDatabaseSslCertificateExpires != nil { + state.TimeDatabaseSslCertificateExpires = types.StringValue(out.TimeDatabaseSslCertificateExpires.Format(time.RFC3339)) + } else { + state.TimeDatabaseSslCertificateExpires = types.StringValue(NotAvailableValues) + } + state.MaintenanceWindow = r.flattenMaintenanceWindow(ctx, out.MaintenanceWindow) + + resp.Diagnostics.Append(flex.Flatten(ctx, out, &state, + flex.WithIgnoredFieldNamesAppend("TimeOrdsCertificateExpires"), + flex.WithIgnoredFieldNamesAppend("TimeDatabaseSslCertificateExpires"))...) + + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (r *resourceCloudAutonomousVmCluster) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + + var plan, state cloudAutonomousVmClusterResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + conn := r.Meta().ODBClient(ctx) + + updateTimeout := r.UpdateTimeout(ctx, plan.Timeouts) + updatedAVMC, err := waitCloudAutonomousVmClusterUpdated(ctx, conn, state.CloudAutonomousVmClusterId.ValueString(), updateTimeout) + + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionWaitingForUpdate, ResNameCloudAutonomousVmCluster, state.CloudAutonomousVmClusterId.String(), err), + err.Error(), + ) + return + } + plan.CreatedAt = types.StringValue(updatedAVMC.CreatedAt.Format(time.RFC3339)) + + if updatedAVMC.TimeDatabaseSslCertificateExpires != nil { + plan.TimeDatabaseSslCertificateExpires = types.StringValue(updatedAVMC.TimeDatabaseSslCertificateExpires.Format(time.RFC3339)) + } else { + plan.TimeDatabaseSslCertificateExpires = types.StringValue(NotAvailableValues) + } + + if updatedAVMC.TimeOrdsCertificateExpires != nil { + plan.TimeOrdsCertificateExpires = types.StringValue(updatedAVMC.TimeOrdsCertificateExpires.Format(time.RFC3339)) + } else { + plan.TimeOrdsCertificateExpires = types.StringValue(NotAvailableValues) + } + plan.MaintenanceWindow = r.flattenMaintenanceWindow(ctx, updatedAVMC.MaintenanceWindow) + resp.Diagnostics.Append(flex.Flatten(ctx, updatedAVMC, &plan, + flex.WithIgnoredFieldNamesAppend("TimeOrdsCertificateExpires"), + flex.WithIgnoredFieldNamesAppend("TimeDatabaseSslCertificateExpires"))...) + + if resp.Diagnostics.HasError() { + return + } + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) +} + +func (r *resourceCloudAutonomousVmCluster) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + + conn := r.Meta().ODBClient(ctx) + + var state cloudAutonomousVmClusterResourceModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + input := odb.DeleteCloudAutonomousVmClusterInput{ + CloudAutonomousVmClusterId: state.CloudAutonomousVmClusterId.ValueStringPointer(), + } + + _, err := conn.DeleteCloudAutonomousVmCluster(ctx, &input) + + if err != nil { + if errs.IsA[*odbtypes.ResourceNotFoundException](err) { + return + } + + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionDeleting, ResNameCloudAutonomousVmCluster, state.CloudAutonomousVmClusterId.ValueString(), err), + err.Error(), + ) + return + } + deleteTimeout := r.DeleteTimeout(ctx, state.Timeouts) + _, err = waitCloudAutonomousVmClusterDeleted(ctx, conn, state.CloudAutonomousVmClusterId.ValueString(), deleteTimeout) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionWaitingForDeletion, ResNameCloudAutonomousVmCluster, state.CloudAutonomousVmClusterId.ValueString(), err), + err.Error(), + ) + return + } +} + +func (r *resourceCloudAutonomousVmCluster) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root(names.AttrID), req, resp) +} + +func waitCloudAutonomousVmClusterCreated(ctx context.Context, conn *odb.Client, id string, timeout time.Duration) (*odbtypes.CloudAutonomousVmCluster, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(odbtypes.ResourceStatusProvisioning), + Target: enum.Slice(odbtypes.ResourceStatusAvailable, odbtypes.ResourceStatusFailed), + Refresh: statusCloudAutonomousVmCluster(ctx, conn, id), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + if out, ok := outputRaw.(*odbtypes.CloudAutonomousVmCluster); ok { + return out, err + } + + return nil, err +} + +func waitCloudAutonomousVmClusterUpdated(ctx context.Context, conn *odb.Client, id string, timeout time.Duration) (*odbtypes.CloudAutonomousVmCluster, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(odbtypes.ResourceStatusUpdating), + Target: enum.Slice(odbtypes.ResourceStatusAvailable, odbtypes.ResourceStatusFailed), + Refresh: statusCloudAutonomousVmCluster(ctx, conn, id), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + if out, ok := outputRaw.(*odbtypes.CloudAutonomousVmCluster); ok { + return out, err + } + + return nil, err +} + +func waitCloudAutonomousVmClusterDeleted(ctx context.Context, conn *odb.Client, id string, timeout time.Duration) (*odbtypes.CloudAutonomousVmCluster, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(odbtypes.ResourceStatusTerminating), + Target: []string{}, + Refresh: statusCloudAutonomousVmCluster(ctx, conn, id), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + if out, ok := outputRaw.(*odbtypes.CloudAutonomousVmCluster); ok { + return out, err + } + + return nil, err +} + +func statusCloudAutonomousVmCluster(ctx context.Context, conn *odb.Client, id string) retry.StateRefreshFunc { + return func() (any, string, error) { + out, err := FindCloudAutonomousVmClusterByID(ctx, conn, id) + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return out, string(out.Status), nil + } +} + +func FindCloudAutonomousVmClusterByID(ctx context.Context, conn *odb.Client, id string) (*odbtypes.CloudAutonomousVmCluster, error) { + input := odb.GetCloudAutonomousVmClusterInput{ + CloudAutonomousVmClusterId: aws.String(id), + } + out, err := conn.GetCloudAutonomousVmCluster(ctx, &input) + if err != nil { + if errs.IsA[*odbtypes.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: &input, + } + } + return nil, err + } + + if out == nil || out.CloudAutonomousVmCluster == nil { + return nil, tfresource.NewEmptyResultError(&input) + } + + return out.CloudAutonomousVmCluster, nil +} + +// TIP: ==== SWEEPERS ==== +// When acceptance testing resources, interrupted or failed tests may +// leave behind orphaned resources in an account. To facilitate cleaning +// up lingering resources, each resource implementation should include +// a corresponding "sweeper" function. +// +// The sweeper function lists all resources of a given type and sets the +// appropriate identifers required to delete the resource via the Delete +// method implemented above. +// +// Once the sweeper function is implemented, register it in sweeper.go +// as follows: +// +// awsv2.Register("aws_odb_cloud_autonomous_vm_cluster", sweepCloudAutonomousVmClusters) +// +// See more: +// https://hashicorp.github.io/terraform-provider-aws/running-and-writing-acceptance-tests/#acceptance-test-sweepers +func sweepCloudAutonomousVmClusters(ctx context.Context, client *conns.AWSClient) ([]sweep.Sweepable, error) { + input := odb.ListCloudAutonomousVmClustersInput{} + conn := client.ODBClient(ctx) + var sweepResources []sweep.Sweepable + + pages := odb.NewListCloudAutonomousVmClustersPaginator(conn, &input) + for pages.HasMorePages() { + page, err := pages.NextPage(ctx) + if err != nil { + return nil, err + } + + for _, v := range page.CloudAutonomousVmClusters { + sweepResources = append(sweepResources, sweepfw.NewSweepResource(newResourceCloudAutonomousVmCluster, client, + sweepfw.NewAttribute(names.AttrID, aws.ToString(v.CloudAutonomousVmClusterId))), + ) + } + } + + return sweepResources, nil +} + +func (r *resourceCloudAutonomousVmCluster) expandMaintenanceWindow(ctx context.Context, avmcMaintenanceWindowFwTypesObj fwtypes.ObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel]) *odbtypes.MaintenanceWindow { + var avmcMaintenanceWindowResource cloudAutonomousVmClusterMaintenanceWindowResourceModel + + avmcMaintenanceWindowFwTypesObj.As(ctx, &avmcMaintenanceWindowResource, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + }) + + var daysOfWeekNames []odbtypes.DayOfWeekName + avmcMaintenanceWindowResource.DaysOfWeek.ElementsAs(ctx, &daysOfWeekNames, false) + daysOfWeek := make([]odbtypes.DayOfWeek, 0, len(daysOfWeekNames)) + + for _, dayOfWeek := range daysOfWeekNames { + daysOfWeek = append(daysOfWeek, odbtypes.DayOfWeek{ + Name: dayOfWeek, + }) + } + + var hoursOfTheDay []int32 + avmcMaintenanceWindowResource.HoursOfDay.ElementsAs(ctx, &hoursOfTheDay, false) + + var monthNames []odbtypes.MonthName + avmcMaintenanceWindowResource.Months.ElementsAs(ctx, &monthNames, false) + months := make([]odbtypes.Month, 0, len(monthNames)) + for _, month := range monthNames { + months = append(months, odbtypes.Month{ + Name: month, + }) + } + + var weeksOfMonth []int32 + avmcMaintenanceWindowResource.WeeksOfMonth.ElementsAs(ctx, &weeksOfMonth, false) + + odbTypeMW := odbtypes.MaintenanceWindow{ + DaysOfWeek: daysOfWeek, + HoursOfDay: hoursOfTheDay, + LeadTimeInWeeks: avmcMaintenanceWindowResource.LeadTimeInWeeks.ValueInt32Pointer(), + Months: months, + Preference: avmcMaintenanceWindowResource.Preference.ValueEnum(), + WeeksOfMonth: weeksOfMonth, + } + if len(odbTypeMW.DaysOfWeek) == 0 { + odbTypeMW.DaysOfWeek = nil + } + if len(odbTypeMW.HoursOfDay) == 0 { + odbTypeMW.HoursOfDay = nil + } + if len(odbTypeMW.Months) == 0 { + odbTypeMW.Months = nil + } + if len(odbTypeMW.WeeksOfMonth) == 0 { + odbTypeMW.WeeksOfMonth = nil + } + if *odbTypeMW.LeadTimeInWeeks == 0 { + odbTypeMW.LeadTimeInWeeks = nil + } + return &odbTypeMW +} + +func (r *resourceCloudAutonomousVmCluster) flattenMaintenanceWindow(ctx context.Context, avmcMW *odbtypes.MaintenanceWindow) fwtypes.ObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel] { + //days of week + daysOfWeek := make([]attr.Value, 0, len(avmcMW.DaysOfWeek)) + for _, dayOfWeek := range avmcMW.DaysOfWeek { + dayOfWeekStringValue := fwtypes.StringEnumValue(dayOfWeek.Name).StringValue + daysOfWeek = append(daysOfWeek, dayOfWeekStringValue) + } + setValueOfDaysOfWeek, _ := basetypes.NewSetValue(types.StringType, daysOfWeek) + daysOfWeekRead := fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.DayOfWeekName]]{ + SetValue: setValueOfDaysOfWeek, + } + //hours of the day + hoursOfTheDay := make([]attr.Value, 0, len(avmcMW.HoursOfDay)) + for _, hourOfTheDay := range avmcMW.HoursOfDay { + daysOfWeekInt32Value := types.Int32Value(hourOfTheDay) + hoursOfTheDay = append(hoursOfTheDay, daysOfWeekInt32Value) + } + setValuesOfHoursOfTheDay, _ := basetypes.NewSetValue(types.Int32Type, hoursOfTheDay) + hoursOfTheDayRead := fwtypes.SetValueOf[types.Int32]{ + SetValue: setValuesOfHoursOfTheDay, + } + //monts + months := make([]attr.Value, 0, len(avmcMW.Months)) + for _, month := range avmcMW.Months { + monthStringValue := fwtypes.StringEnumValue(month.Name).StringValue + months = append(months, monthStringValue) + } + setValuesOfMonth, _ := basetypes.NewSetValue(types.StringType, months) + monthsRead := fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.MonthName]]{ + SetValue: setValuesOfMonth, + } + //weeks of month + weeksOfMonth := make([]attr.Value, 0, len(avmcMW.WeeksOfMonth)) + for _, weekOfMonth := range avmcMW.WeeksOfMonth { + weeksOfMonthInt32Value := types.Int32Value(weekOfMonth) + weeksOfMonth = append(weeksOfMonth, weeksOfMonthInt32Value) + } + setValuesOfWeekOfMonth, _ := basetypes.NewSetValue(types.Int32Type, weeksOfMonth) + weeksOfMonthRead := fwtypes.SetValueOf[types.Int32]{ + SetValue: setValuesOfWeekOfMonth, + } + + computedMW := cloudAutonomousVmClusterMaintenanceWindowResourceModel{ + DaysOfWeek: daysOfWeekRead, + HoursOfDay: hoursOfTheDayRead, + LeadTimeInWeeks: types.Int32PointerValue(avmcMW.LeadTimeInWeeks), + Months: monthsRead, + Preference: fwtypes.StringEnumValue(avmcMW.Preference), + WeeksOfMonth: weeksOfMonthRead, + } + if avmcMW.LeadTimeInWeeks == nil { + computedMW.LeadTimeInWeeks = types.Int32Value(0) + } + result, _ := fwtypes.NewObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel](ctx, &computedMW) + return result +} + +type cloudAutonomousVmClusterResourceModel struct { + framework.WithRegionModel + CloudAutonomousVmClusterArn types.String `tfsdk:"arn"` + CloudAutonomousVmClusterId types.String `tfsdk:"id"` + CloudExadataInfrastructureId types.String `tfsdk:"cloud_exadata_infrastructure_id"` + AutonomousDataStoragePercentage types.Float32 `tfsdk:"autonomous_data_storage_percentage"` + AutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"autonomous_data_storage_size_in_tbs"` + AvailableAutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"available_autonomous_data_storage_size_in_tbs"` + AvailableContainerDatabases types.Int32 `tfsdk:"available_container_databases"` + AvailableCpus types.Float32 `tfsdk:"available_cpus"` + ComputeModel fwtypes.StringEnum[odbtypes.ComputeModel] `tfsdk:"compute_model"` + CpuCoreCount types.Int32 `tfsdk:"cpu_core_count"` + CpuCoreCountPerNode types.Int32 `tfsdk:"cpu_core_count_per_node"` + CpuPercentage types.Float32 `tfsdk:"cpu_percentage"` + CreatedAt types.String `tfsdk:"created_at" autoflex:",noflatten"` + DataStorageSizeInGBs types.Float64 `tfsdk:"data_storage_size_in_gbs"` + DataStorageSizeInTBs types.Float64 `tfsdk:"data_storage_size_in_tbs"` + DbNodeStorageSizeInGBs types.Int32 `tfsdk:"odb_node_storage_size_in_gbs"` + DbServers fwtypes.SetValueOf[types.String] `tfsdk:"db_servers"` + Description types.String `tfsdk:"description"` + DisplayName types.String `tfsdk:"display_name"` + Domain types.String `tfsdk:"domain"` + ExadataStorageInTBsLowestScaledValue types.Float64 `tfsdk:"exadata_storage_in_tbs_lowest_scaled_value"` + Hostname types.String `tfsdk:"hostname"` + IsMtlsEnabledVmCluster types.Bool `tfsdk:"is_mtls_enabled_vm_cluster"` + LicenseModel fwtypes.StringEnum[odbtypes.LicenseModel] `tfsdk:"license_model"` + MaxAcdsLowestScaledValue types.Int32 `tfsdk:"max_acds_lowest_scaled_value"` + MemoryPerOracleComputeUnitInGBs types.Int32 `tfsdk:"memory_per_oracle_compute_unit_in_gbs"` + MemorySizeInGBs types.Int32 `tfsdk:"memory_size_in_gbs"` + NodeCount types.Int32 `tfsdk:"node_count"` + NonProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"non_provisionable_autonomous_container_databases"` + OciResourceAnchorName types.String `tfsdk:"oci_resource_anchor_name"` + OciUrl types.String `tfsdk:"oci_url"` + Ocid types.String `tfsdk:"ocid"` + OdbNetworkId types.String `tfsdk:"odb_network_id"` + PercentProgress types.Float32 `tfsdk:"percent_progress"` + ProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"provisionable_autonomous_container_databases"` + ProvisionedAutonomousContainerDatabases types.Int32 `tfsdk:"provisioned_autonomous_container_databases"` + ProvisionedCpus types.Float32 `tfsdk:"provisioned_cpus"` + ReclaimableCpus types.Float32 `tfsdk:"reclaimable_cpus"` + ReservedCpus types.Float32 `tfsdk:"reserved_cpus"` + ScanListenerPortNonTls types.Int32 `tfsdk:"scan_listener_port_non_tls"` + ScanListenerPortTls types.Int32 `tfsdk:"scan_listener_port_tls"` + Shape types.String `tfsdk:"shape"` + Status fwtypes.StringEnum[odbtypes.ResourceStatus] `tfsdk:"status"` + StatusReason types.String `tfsdk:"status_reason"` + TimeZone types.String `tfsdk:"time_zone"` + TotalContainerDatabases types.Int32 `tfsdk:"total_container_databases"` + Timeouts timeouts.Value `tfsdk:"timeouts"` + Tags tftags.Map `tfsdk:"tags"` + TagsAll tftags.Map `tfsdk:"tags_all"` + TimeOrdsCertificateExpires types.String `tfsdk:"time_ords_certificate_expires"` + TimeDatabaseSslCertificateExpires types.String `tfsdk:"time_database_ssl_certificate_expires"` + MaintenanceWindow fwtypes.ObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"maintenance_window" autoflex:"-"` +} + +type cloudAutonomousVmClusterMaintenanceWindowResourceModel struct { + DaysOfWeek fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.DayOfWeekName]] `tfsdk:"days_of_week"` + HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` + LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` + Months fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.MonthName]] `tfsdk:"months"` + Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` + WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` +} diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go new file mode 100644 index 000000000000..ce561fff9d4d --- /dev/null +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go @@ -0,0 +1,433 @@ +//Copyright © 2025, Oracle and/or its affiliates. All rights reserved. + +package odb + +import ( + "context" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "time" + + "github.com/aws/aws-sdk-go-v2/service/odb" + odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// Function annotations are used for datasource registration to the Provider. DO NOT EDIT. +// @FrameworkDataSource("aws_odb_cloud_autonomous_vm_cluster", name="Cloud Autonomous Vm Cluster") +func newDataSourceCloudAutonomousVmCluster(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceCloudAutonomousVmCluster{}, nil +} + +const ( + DSNameCloudAutonomousVmCluster = "Cloud Autonomous Vm Cluster Data Source" +) + +type dataSourceCloudAutonomousVmCluster struct { + framework.DataSourceWithModel[cloudAutonomousVmClusterDataSourceModel] +} + +func (d *dataSourceCloudAutonomousVmCluster) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + status := fwtypes.StringEnumType[odbtypes.ResourceStatus]() + licenseModel := fwtypes.StringEnumType[odbtypes.LicenseModel]() + computeModel := fwtypes.StringEnumType[odbtypes.ComputeModel]() + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + names.AttrARN: framework.ARNAttributeComputedOnly(), + + names.AttrID: schema.StringAttribute{ + Required: true, + Description: "Unique ID of the Autonomous VM cluster.", + }, + "cloud_exadata_infrastructure_id": schema.StringAttribute{ + Computed: true, + Description: "Cloud exadata infrastructure id associated with this cloud autonomous VM cluster.", + }, + "autonomous_data_storage_percentage": schema.Float32Attribute{ + Computed: true, + Description: "The percentage of data storage currently in use for Autonomous Databases in the Autonomous VM cluster.", + }, + "autonomous_data_storage_size_in_tbs": schema.Float64Attribute{ + Computed: true, + Description: "The data storage size allocated for Autonomous Databases in the Autonomous VM cluster, in TB.", + }, + "available_autonomous_data_storage_size_in_tbs": schema.Float64Attribute{ + Computed: true, + Description: "The available data storage space for Autonomous Databases in the Autonomous VM cluster, in TB.", + }, + "available_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that you can create with the currently available storage.", + }, + "available_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores available for allocation to Autonomous Databases.", + }, + "compute_model": schema.StringAttribute{ + CustomType: computeModel, + Computed: true, + Description: " The compute model of the Autonomous VM cluster: ECPU or OCPU.", + }, + "cpu_core_count": schema.Int32Attribute{ + Computed: true, + Description: "The total number of CPU cores in the Autonomous VM cluster.", + }, + "cpu_core_count_per_node": schema.Int32Attribute{ + Computed: true, + Description: "The number of CPU cores enabled per node in the Autonomous VM cluster.", + }, + "cpu_percentage": schema.Float32Attribute{ + Computed: true, + Description: "he percentage of total CPU cores currently in use in the Autonomous VM cluster.", + }, + "created_at": schema.StringAttribute{ + Computed: true, + Description: "The date and time when the Autonomous VM cluster was created.", + }, + "data_storage_size_in_gbs": schema.Float64Attribute{ + Computed: true, + Description: "The total data storage allocated to the Autonomous VM cluster, in GB.", + }, + "data_storage_size_in_tbs": schema.Float64Attribute{ + Computed: true, + Description: "The total data storage allocated to the Autonomous VM cluster, in TB.", + }, + "odb_node_storage_size_in_gbs": schema.Int32Attribute{ + Computed: true, + Description: "The local node storage allocated to the Autonomous VM cluster, in gigabytes (GB).", + }, + "db_servers": schema.SetAttribute{ + Computed: true, + CustomType: fwtypes.SetOfStringType, + ElementType: types.StringType, + Description: "The list of database servers associated with the Autonomous VM cluster.", + }, + "description": schema.StringAttribute{ + Computed: true, + Description: "The user-provided description of the Autonomous VM cluster.", + }, + "display_name": schema.StringAttribute{ + Computed: true, + Description: "The display name of the Autonomous VM cluster.", + }, + "domain": schema.StringAttribute{ + Computed: true, + Description: "The domain name of the Autonomous VM cluster.", + }, + "exadata_storage_in_tbs_lowest_scaled_value": schema.Float64Attribute{ + Computed: true, + Description: "The minimum value to which you can scale down the Exadata storage, in TB.", + }, + "hostname": schema.StringAttribute{ + Computed: true, + Description: "The hostname of the Autonomous VM cluster.", + }, + "is_mtls_enabled_vm_cluster": schema.BoolAttribute{ + Computed: true, + Description: " Indicates whether mutual TLS (mTLS) authentication is enabled for the Autonomous VM cluster.", + }, + "license_model": schema.StringAttribute{ + CustomType: licenseModel, + Computed: true, + Description: "The Oracle license model that applies to the Autonomous VM cluster. Valid values are LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE .", + }, + "max_acds_lowest_scaled_value": schema.Int32Attribute{ + Computed: true, + Description: "The minimum value to which you can scale down the maximum number of Autonomous CDBs.", + }, + "memory_per_oracle_compute_unit_in_gbs": schema.Int32Attribute{ + Computed: true, + Description: "The amount of memory allocated per Oracle Compute Unit, in GB.", + }, + "memory_size_in_gbs": schema.Int32Attribute{ + Computed: true, + Description: "The total amount of memory allocated to the Autonomous VM cluster, in gigabytes (GB).", + }, + "node_count": schema.Int32Attribute{ + Computed: true, + Description: "The number of database server nodes in the Autonomous VM cluster.", + }, + "non_provisionable_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that can't be provisioned because of resource constraints.", + }, + "oci_resource_anchor_name": schema.StringAttribute{ + Computed: true, + Description: "The name of the OCI resource anchor associated with this Autonomous VM cluster.", + }, + "oci_url": schema.StringAttribute{ + Computed: true, + Description: "The URL for accessing the OCI console page for this Autonomous VM cluster.", + }, + "ocid": schema.StringAttribute{ + Computed: true, + Description: "The Oracle Cloud Identifier (OCID) of the Autonomous VM cluster.", + }, + "odb_network_id": schema.StringAttribute{ + Computed: true, + Description: "The unique identifier of the ODB network associated with this Autonomous VM cluster.", + }, + "percent_progress": schema.Float32Attribute{ + Computed: true, + Description: "The progress of the current operation on the Autonomous VM cluster, as a percentage.", + }, + "provisionable_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that can be provisioned in the Autonomous VM cluster.", + }, + "provisioned_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs currently provisioned in the Autonomous VM cluster.", + }, + "provisioned_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores currently provisioned in the Autonomous VM cluster.", + }, + "reclaimable_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores that can be reclaimed from terminated or scaled-down Autonomous Databases.", + }, + "reserved_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores reserved for system operations and redundancy.", + }, + "scan_listener_port_non_tls": schema.Int32Attribute{ + Computed: true, + Description: "The SCAN listener port for non-TLS (TCP) protocol. The default is 1521.", + }, + "scan_listener_port_tls": schema.Int32Attribute{ + Computed: true, + Description: "The SCAN listener port for TLS (TCP) protocol. The default is 2484.", + }, + "shape": schema.StringAttribute{ + Computed: true, + Description: "The shape of the Exadata infrastructure for the Autonomous VM cluster.", + }, + "status": schema.StringAttribute{ + CustomType: status, + Computed: true, + Description: "The status of the Autonomous VM cluster.", + }, + "status_reason": schema.StringAttribute{ + Computed: true, + Description: "Additional information about the current status of the Autonomous VM cluster.", + }, + "time_database_ssl_certificate_expires": schema.StringAttribute{ + Computed: true, + Description: "The expiration date and time of the database SSL certificate.", + }, + "time_ords_certificate_expires": schema.StringAttribute{ + Computed: true, + Description: "The expiration date and time of the Oracle REST Data Services (ORDS)certificate .", + }, + "time_zone": schema.StringAttribute{ + Computed: true, + Description: "The time zone of the Autonomous VM cluster.", + }, + "total_container_databases": schema.Int32Attribute{ + Computed: true, + }, + names.AttrTags: tftags.TagsAttributeComputedOnly(), + "maintenance_window": schema.ObjectAttribute{ + Computed: true, + CustomType: fwtypes.NewObjectTypeOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel](ctx), + Description: "The maintenance window for the Autonomous VM cluster.", + AttributeTypes: map[string]attr.Type{ + "days_of_week": types.SetType{ + ElemType: fwtypes.StringEnumType[odbtypes.DayOfWeekName](), + }, + "hours_of_day": types.SetType{ + ElemType: types.Int32Type, + }, + "lead_time_in_weeks": types.Int32Type, + "months": types.SetType{ + ElemType: fwtypes.StringEnumType[odbtypes.MonthName](), + }, + "preference": fwtypes.StringEnumType[odbtypes.PreferenceType](), + "weeks_of_month": types.SetType{ + ElemType: types.Int32Type, + }, + }, + }, + }, + } +} + +func (d *dataSourceCloudAutonomousVmCluster) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + + conn := d.Meta().ODBClient(ctx) + + var data cloudAutonomousVmClusterDataSourceModel + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + input := odb.GetCloudAutonomousVmClusterInput{ + CloudAutonomousVmClusterId: data.CloudAutonomousVmClusterId.ValueStringPointer(), + } + + out, err := conn.GetCloudAutonomousVmCluster(ctx, &input) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionReading, DSNameCloudAutonomousVmCluster, data.CloudAutonomousVmClusterId.ValueString(), err), + err.Error(), + ) + return + } + data.CreatedAt = types.StringValue(out.CloudAutonomousVmCluster.CreatedAt.Format(time.RFC3339)) + if out.CloudAutonomousVmCluster.TimeOrdsCertificateExpires != nil { + data.TimeOrdsCertificateExpires = types.StringValue(out.CloudAutonomousVmCluster.TimeOrdsCertificateExpires.Format(time.RFC3339)) + } else { + data.TimeOrdsCertificateExpires = types.StringValue(NotAvailableValues) + } + if out.CloudAutonomousVmCluster.TimeDatabaseSslCertificateExpires != nil { + data.TimeDatabaseSslCertificateExpires = types.StringValue(out.CloudAutonomousVmCluster.TimeDatabaseSslCertificateExpires.Format(time.RFC3339)) + } else { + data.TimeDatabaseSslCertificateExpires = types.StringValue(NotAvailableValues) + } + tagsRead, err := listTags(ctx, conn, *out.CloudAutonomousVmCluster.CloudAutonomousVmClusterArn) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionReading, DSNameCloudAutonomousVmCluster, data.CloudAutonomousVmClusterId.ValueString(), err), + err.Error(), + ) + return + } + if tagsRead != nil { + data.Tags = tftags.FlattenStringValueMap(ctx, tagsRead.Map()) + } + + data.MaintenanceWindow = d.flattenMaintenanceWindow(ctx, out.CloudAutonomousVmCluster.MaintenanceWindow) + + resp.Diagnostics.Append(flex.Flatten(ctx, out.CloudAutonomousVmCluster, &data)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (d *dataSourceCloudAutonomousVmCluster) flattenMaintenanceWindow(ctx context.Context, avmcMW *odbtypes.MaintenanceWindow) fwtypes.ObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel] { + //days of week + daysOfWeek := make([]attr.Value, 0, len(avmcMW.DaysOfWeek)) + for _, dayOfWeek := range avmcMW.DaysOfWeek { + dayOfWeekStringValue := fwtypes.StringEnumValue(dayOfWeek.Name).StringValue + daysOfWeek = append(daysOfWeek, dayOfWeekStringValue) + } + setValueOfDaysOfWeek, _ := basetypes.NewSetValue(types.StringType, daysOfWeek) + daysOfWeekRead := fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.DayOfWeekName]]{ + SetValue: setValueOfDaysOfWeek, + } + //hours of the day + hoursOfTheDay := make([]attr.Value, 0, len(avmcMW.HoursOfDay)) + for _, hourOfTheDay := range avmcMW.HoursOfDay { + daysOfWeekInt32Value := types.Int32Value(hourOfTheDay) + hoursOfTheDay = append(hoursOfTheDay, daysOfWeekInt32Value) + } + setValuesOfHoursOfTheDay, _ := basetypes.NewSetValue(types.Int32Type, hoursOfTheDay) + hoursOfTheDayRead := fwtypes.SetValueOf[types.Int32]{ + SetValue: setValuesOfHoursOfTheDay, + } + //monts + months := make([]attr.Value, 0, len(avmcMW.Months)) + for _, month := range avmcMW.Months { + monthStringValue := fwtypes.StringEnumValue(month.Name).StringValue + months = append(months, monthStringValue) + } + setValuesOfMonth, _ := basetypes.NewSetValue(types.StringType, months) + monthsRead := fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.MonthName]]{ + SetValue: setValuesOfMonth, + } + //weeks of month + weeksOfMonth := make([]attr.Value, 0, len(avmcMW.WeeksOfMonth)) + for _, weekOfMonth := range avmcMW.WeeksOfMonth { + weeksOfMonthInt32Value := types.Int32Value(weekOfMonth) + weeksOfMonth = append(weeksOfMonth, weeksOfMonthInt32Value) + } + setValuesOfWeekOfMonth, _ := basetypes.NewSetValue(types.Int32Type, weeksOfMonth) + weeksOfMonthRead := fwtypes.SetValueOf[types.Int32]{ + SetValue: setValuesOfWeekOfMonth, + } + + computedMW := cloudAutonomousVmClusterMaintenanceWindowDataSourceModel{ + DaysOfWeek: daysOfWeekRead, + HoursOfDay: hoursOfTheDayRead, + LeadTimeInWeeks: types.Int32PointerValue(avmcMW.LeadTimeInWeeks), + Months: monthsRead, + Preference: fwtypes.StringEnumValue(avmcMW.Preference), + WeeksOfMonth: weeksOfMonthRead, + } + result, _ := fwtypes.NewObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel](ctx, &computedMW) + return result +} + +type cloudAutonomousVmClusterDataSourceModel struct { + framework.WithRegionModel + CloudAutonomousVmClusterArn types.String `tfsdk:"arn"` + CloudAutonomousVmClusterId types.String `tfsdk:"id"` + CloudExadataInfrastructureId types.String `tfsdk:"cloud_exadata_infrastructure_id"` + AutonomousDataStoragePercentage types.Float32 `tfsdk:"autonomous_data_storage_percentage"` + AutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"autonomous_data_storage_size_in_tbs"` + AvailableAutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"available_autonomous_data_storage_size_in_tbs"` + AvailableContainerDatabases types.Int32 `tfsdk:"available_container_databases"` + AvailableCpus types.Float32 `tfsdk:"available_cpus"` + ComputeModel fwtypes.StringEnum[odbtypes.ComputeModel] `tfsdk:"compute_model"` + CpuCoreCount types.Int32 `tfsdk:"cpu_core_count"` + CpuCoreCountPerNode types.Int32 `tfsdk:"cpu_core_count_per_node"` + CpuPercentage types.Float32 `tfsdk:"cpu_percentage"` + CreatedAt types.String `tfsdk:"created_at" autoflex:",noflatten"` + DataStorageSizeInGBs types.Float64 `tfsdk:"data_storage_size_in_gbs"` + DataStorageSizeInTBs types.Float64 `tfsdk:"data_storage_size_in_tbs"` + DbNodeStorageSizeInGBs types.Int32 `tfsdk:"odb_node_storage_size_in_gbs"` + DbServers fwtypes.SetValueOf[types.String] `tfsdk:"db_servers"` + Description types.String `tfsdk:"description"` + DisplayName types.String `tfsdk:"display_name"` + Domain types.String `tfsdk:"domain"` + ExadataStorageInTBsLowestScaledValue types.Float64 `tfsdk:"exadata_storage_in_tbs_lowest_scaled_value"` + Hostname types.String `tfsdk:"hostname"` + IsMtlsEnabledVmCluster types.Bool `tfsdk:"is_mtls_enabled_vm_cluster"` + LicenseModel fwtypes.StringEnum[odbtypes.LicenseModel] `tfsdk:"license_model"` + MaxAcdsLowestScaledValue types.Int32 `tfsdk:"max_acds_lowest_scaled_value"` + MemoryPerOracleComputeUnitInGBs types.Int32 `tfsdk:"memory_per_oracle_compute_unit_in_gbs"` + MemorySizeInGBs types.Int32 `tfsdk:"memory_size_in_gbs"` + NodeCount types.Int32 `tfsdk:"node_count"` + NonProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"non_provisionable_autonomous_container_databases"` + OciResourceAnchorName types.String `tfsdk:"oci_resource_anchor_name"` + OciUrl types.String `tfsdk:"oci_url"` + Ocid types.String `tfsdk:"ocid"` + OdbNetworkId types.String `tfsdk:"odb_network_id"` + PercentProgress types.Float32 `tfsdk:"percent_progress"` + ProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"provisionable_autonomous_container_databases"` + ProvisionedAutonomousContainerDatabases types.Int32 `tfsdk:"provisioned_autonomous_container_databases"` + ProvisionedCpus types.Float32 `tfsdk:"provisioned_cpus"` + ReclaimableCpus types.Float32 `tfsdk:"reclaimable_cpus"` + ReservedCpus types.Float32 `tfsdk:"reserved_cpus"` + ScanListenerPortNonTls types.Int32 `tfsdk:"scan_listener_port_non_tls"` + ScanListenerPortTls types.Int32 `tfsdk:"scan_listener_port_tls"` + Shape types.String `tfsdk:"shape"` + Status fwtypes.StringEnum[odbtypes.ResourceStatus] `tfsdk:"status"` + StatusReason types.String `tfsdk:"status_reason"` + TimeDatabaseSslCertificateExpires types.String `tfsdk:"time_database_ssl_certificate_expires" autoflex:",noflatten"` + TimeOrdsCertificateExpires types.String `tfsdk:"time_ords_certificate_expires" autoflex:",noflatten"` + TimeZone types.String `tfsdk:"time_zone"` + TotalContainerDatabases types.Int32 `tfsdk:"total_container_databases"` + MaintenanceWindow fwtypes.ObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"maintenance_window" autoflex:",noflatten"` + Tags tftags.Map `tfsdk:"tags"` +} +type cloudAutonomousVmClusterMaintenanceWindowDataSourceModel struct { + DaysOfWeek fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.DayOfWeekName]] `tfsdk:"days_of_week"` + HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` + LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` + Months fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.MonthName]] `tfsdk:"months"` + Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` + WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` +} diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go new file mode 100644 index 000000000000..8061ab284f3f --- /dev/null +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go @@ -0,0 +1,242 @@ +//Copyright © 2025, Oracle and/or its affiliates. All rights reserved. + +package odb_test + +import ( + "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/odb" + odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/errs" + tfodb "github.com/hashicorp/terraform-provider-aws/internal/service/odb" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +type autonomousVMClusterDSTest struct { + exaInfraDisplayNamePrefix string + odbNetDisplayNamePrefix string + autonomousVmClusterDisplayNamePrefix string +} + +var autonomousVMClusterDSTestEntity = autonomousVMClusterDSTest{ + exaInfraDisplayNamePrefix: "Ofake-exa", + odbNetDisplayNamePrefix: "odb-net", + autonomousVmClusterDisplayNamePrefix: "Ofake-avmc", +} + +func TestAccODBCloudAutonomousVmClusterDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var avmc1 odbtypes.CloudAutonomousVmCluster + dataSourceName := "data.aws_odb_cloud_autonomous_vm_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + autonomousVMClusterDSTestEntity.testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ODBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: autonomousVMClusterDSTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: autonomousVMClusterDSTestEntity.avmcBasic(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "display_name", *avmc1.DisplayName), + ), + }, + }, + }) +} +func (autonomousVMClusterDSTest) checkCloudAutonomousVmClusterExists(ctx context.Context, name string, cloudAutonomousVMCluster *odbtypes.CloudAutonomousVmCluster) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, name, errors.New("not found")) + } + + if rs.Primary.ID == "" { + return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, name, errors.New("not set")) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + resp, err := autonomousVMClusterDSTestEntity.findAVMC(ctx, conn, rs.Primary.ID) + if err != nil { + return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, err) + } + + *cloudAutonomousVMCluster = *resp + + return nil + } +} + +func (autonomousVMClusterDSTest) findAVMC(ctx context.Context, conn *odb.Client, id string) (*odbtypes.CloudAutonomousVmCluster, error) { + input := odb.GetCloudAutonomousVmClusterInput{ + CloudAutonomousVmClusterId: aws.String(id), + } + out, err := conn.GetCloudAutonomousVmCluster(ctx, &input) + if err != nil { + if errs.IsA[*odbtypes.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: &input, + } + } + return nil, err + } + + if out == nil || out.CloudAutonomousVmCluster == nil { + return nil, tfresource.NewEmptyResultError(&input) + } + + return out.CloudAutonomousVmCluster, nil +} + +func (autonomousVMClusterDSTest) testAccCheckCloudAutonomousVmClusterDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_odb_cloud_autonomous_vm_cluster" { + continue + } + + _, err := tfodb.FindCloudAutonomousVmClusterByID(ctx, conn, rs.Primary.ID) + if tfresource.NotFound(err) { + return nil + } + if err != nil { + return create.Error(names.ODB, create.ErrActionCheckingDestroyed, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, err) + } + + return create.Error(names.ODB, create.ErrActionCheckingDestroyed, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, errors.New("not destroyed")) + } + + return nil + } +} +func (autonomousVMClusterDSTest) testAccPreCheck(ctx context.Context, t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + + input := &odb.ListCloudAutonomousVmClustersInput{} + + _, err := conn.ListCloudAutonomousVmClusters(ctx, input) + + if acctest.PreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) + } + if err != nil { + t.Fatalf("unexpected PreCheck error: %s", err) + } +} + +func (autonomousVMClusterDSTest) avmcBasic() string { + + exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) + odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) + avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) + + exaInfraRes := autonomousVMClusterDSTestEntity.exaInfra(exaInfraDisplayName) + odbNetRes := autonomousVMClusterDSTestEntity.odbNet(odbNetworkDisplayName) + res := fmt.Sprintf(` +%s + +%s + +data "aws_odb_db_servers_list" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id +} + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id =aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [ for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "NO_PREFERENCE" + days_of_week = [] + hours_of_day = [] + months = [] + weeks_of_month =[] + lead_time_in_weeks = 0 + } + +} + + +data "aws_odb_cloud_autonomous_vm_cluster" "test" { + id = aws_odb_cloud_autonomous_vm_cluster.test.id + +} +`, exaInfraRes, odbNetRes, avmcDisplayName) + + return res +} + +func (autonomousVMClusterDSTest) odbNet(odbNetName string) string { + networkRes := fmt.Sprintf(` + + +resource "aws_odb_network" "test" { + display_name = %[1]q + availability_zone_id = "use1-az6" + client_subnet_cidr = "10.2.0.0/24" + backup_subnet_cidr = "10.2.1.0/24" + s3_access = "DISABLED" + zero_etl_access = "DISABLED" +} + +`, odbNetName) + return networkRes +} + +func (autonomousVMClusterDSTest) exaInfra(exaInfraName string) string { + exaInfraRes := fmt.Sprintf(` + + +resource "aws_odb_cloud_exadata_infrastructure" "test" { + display_name = %[1]q + shape = "Exadata.X9M" + storage_count = 3 + compute_count = 2 + availability_zone_id = "use1-az6" + customer_contacts_to_send_to_oci = ["abc@example.com"] +maintenance_window = { + custom_action_timeout_in_mins = 16 + days_of_week = [] + hours_of_day = [] + is_custom_action_timeout_enabled = true + lead_time_in_weeks = 0 + months = [] + patching_mode = "ROLLING" + preference = "NO_PREFERENCE" + weeks_of_month =[] + } +} + +`, exaInfraName) + return exaInfraRes +} diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go new file mode 100644 index 000000000000..21068944bc09 --- /dev/null +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -0,0 +1,533 @@ +//Copyright © 2025, Oracle and/or its affiliates. All rights reserved. + +package odb_test + +import ( + "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/odb" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-provider-aws/internal/errs" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "strings" + "testing" + + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + + "github.com/hashicorp/terraform-provider-aws/names" + + odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" + + tfodb "github.com/hashicorp/terraform-provider-aws/internal/service/odb" +) + +type autonomousVMClusterResourceTest struct { + exaInfraDisplayNamePrefix string + odbNetDisplayNamePrefix string + autonomousVmClusterDisplayNamePrefix string +} + +var autonomousVMClusterResourceTestEntity = autonomousVMClusterResourceTest{ + exaInfraDisplayNamePrefix: "Ofake-exa", + odbNetDisplayNamePrefix: "odb-net", + autonomousVmClusterDisplayNamePrefix: "Ofake-avmc", +} + +func TestAccODBCloudAutonomousVmClusterCreationBasic(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var cloudAVMC odbtypes.CloudAutonomousVmCluster + + resourceName := "aws_odb_cloud_autonomous_vm_cluster.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + autonomousVMClusterResourceTestEntity.testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ODBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: autonomousVMClusterResourceTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: autonomousVMClusterResourceTestEntity.avmcBasic(), + Check: resource.ComposeAggregateTestCheckFunc( + autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &cloudAVMC), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccODBCloudAutonomousVmClusterCreationWithAllParams(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var cloudAVMC odbtypes.CloudAutonomousVmCluster + + resourceName := "aws_odb_cloud_autonomous_vm_cluster.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + //acctest.PreCheckPartitionHasService(t, names.ODBServiceID) + autonomousVMClusterResourceTestEntity.testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ODBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: autonomousVMClusterResourceTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: autonomousVMClusterResourceTestEntity.avmcAllParamsConfig(), + Check: resource.ComposeAggregateTestCheckFunc( + autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &cloudAVMC), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccODBCloudAutonomousVmClusterTagging(t *testing.T) { + fmt.Println("Update tags test") + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var avmc1, avmc2 odbtypes.CloudAutonomousVmCluster + resourceName := "aws_odb_cloud_autonomous_vm_cluster.test" + withoutTag, withTag := autonomousVMClusterResourceTestEntity.avmcNoTagWithTag() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + autonomousVMClusterResourceTestEntity.testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ODBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: autonomousVMClusterResourceTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), + + Steps: []resource.TestStep{ + { + Config: withoutTag, + + Check: resource.ComposeAggregateTestCheckFunc( + autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &avmc1), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: withTag, + Check: resource.ComposeAggregateTestCheckFunc( + autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &avmc2), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.env", "dev"), + resource.ComposeTestCheckFunc(func(state *terraform.State) error { + if strings.Compare(*(avmc1.CloudAutonomousVmClusterId), *(avmc2.CloudAutonomousVmClusterId)) != 0 { + return errors.New("shouldn't create a new autonomous vm cluster") + } + return nil + }), + ), + }, + }, + }) +} + +func TestAccODBCloudAutonomousVmCluster_disappears(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var cloudautonomousvmcluster odbtypes.CloudAutonomousVmCluster + resourceName := "aws_odb_cloud_autonomous_vm_cluster.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + autonomousVMClusterResourceTestEntity.testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ODBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: autonomousVMClusterResourceTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: autonomousVMClusterResourceTestEntity.avmcBasic_hardCoded(), + Check: resource.ComposeAggregateTestCheckFunc( + autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &cloudautonomousvmcluster), + acctest.CheckFrameworkResourceDisappears(ctx, acctest.Provider, tfodb.ResourceCloudAutonomousVMCluster, resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func (autonomousVMClusterResourceTest) testAccPreCheck(ctx context.Context, t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + + input := &odb.ListCloudAutonomousVmClustersInput{} + + _, err := conn.ListCloudAutonomousVmClusters(ctx, input) + + if acctest.PreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) + } + if err != nil { + t.Fatalf("unexpected PreCheck error: %s", err) + } +} +func (autonomousVMClusterResourceTest) testAccCheckCloudAutonomousVmClusterDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_odb_cloud_autonomous_vm_cluster" { + continue + } + + _, err := autonomousVMClusterResourceTestEntity.findAVMC(ctx, conn, rs.Primary.ID) + if tfresource.NotFound(err) { + return nil + } + if err != nil { + return create.Error(names.ODB, create.ErrActionCheckingDestroyed, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, err) + } + + return create.Error(names.ODB, create.ErrActionCheckingDestroyed, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, errors.New("not destroyed")) + } + + return nil + } +} + +func (autonomousVMClusterResourceTest) checkCloudAutonomousVmClusterExists(ctx context.Context, name string, cloudAutonomousVMCluster *odbtypes.CloudAutonomousVmCluster) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, name, errors.New("not found")) + } + + if rs.Primary.ID == "" { + return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, name, errors.New("not set")) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + fmt.Println("") + resp, err := autonomousVMClusterResourceTestEntity.findAVMC(ctx, conn, rs.Primary.ID) + if err != nil { + return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, err) + } + + *cloudAutonomousVMCluster = *resp + + return nil + } +} + +func (autonomousVMClusterResourceTest) findAVMC(ctx context.Context, conn *odb.Client, id string) (*odbtypes.CloudAutonomousVmCluster, error) { + input := odb.GetCloudAutonomousVmClusterInput{ + CloudAutonomousVmClusterId: aws.String(id), + } + out, err := conn.GetCloudAutonomousVmCluster(ctx, &input) + if err != nil { + if errs.IsA[*odbtypes.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: &input, + } + } + return nil, err + } + + if out == nil || out.CloudAutonomousVmCluster == nil { + return nil, tfresource.NewEmptyResultError(&input) + } + + return out.CloudAutonomousVmCluster, nil +} + +func (autonomousVMClusterResourceTest) avmcBasic() string { + + exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) + odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) + avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) + + exaInfraRes := autonomousVMClusterDSTestEntity.exaInfra(exaInfraDisplayName) + odbNetRes := autonomousVMClusterDSTestEntity.odbNet(odbNetworkDisplayName) + res := fmt.Sprintf(` +%s + +%s + +data "aws_odb_db_servers_list" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id +} + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id =aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [ for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "NO_PREFERENCE" + days_of_week = [] + hours_of_day = [] + months = [] + weeks_of_month =[] + lead_time_in_weeks = 0 + } + +} + +`, exaInfraRes, odbNetRes, avmcDisplayName) + + return res +} + +func (autonomousVMClusterResourceTest) avmcNoTagWithTag() (string, string) { + exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) + odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) + avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) + + exaInfraRes := autonomousVMClusterDSTestEntity.exaInfra(exaInfraDisplayName) + odbNetRes := autonomousVMClusterDSTestEntity.odbNet(odbNetworkDisplayName) + noTag := fmt.Sprintf(` +%s + +%s + +data "aws_odb_db_servers_list" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id +} + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id =aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [ for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "NO_PREFERENCE" + days_of_week = [] + hours_of_day = [] + months = [] + weeks_of_month =[] + lead_time_in_weeks = 0 + } + +} + +`, exaInfraRes, odbNetRes, avmcDisplayName) + withTag := fmt.Sprintf(` +%s + +%s + +data "aws_odb_db_servers_list" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id +} + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id =aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [ for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "NO_PREFERENCE" + days_of_week = [] + hours_of_day = [] + months = [] + weeks_of_month =[] + lead_time_in_weeks = 0 + } + tags = { + "env"= "dev" + } + +} + +`, exaInfraRes, odbNetRes, avmcDisplayName) + + return noTag, withTag +} + +func (autonomousVMClusterResourceTest) avmcAllParamsConfig() string { + + exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) + odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) + avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) + + exaInfraRes := autonomousVMClusterDSTestEntity.exaInfra(exaInfraDisplayName) + odbNetRes := autonomousVMClusterDSTestEntity.odbNet(odbNetworkDisplayName) + res := fmt.Sprintf(` +%s + +%s + +data "aws_odb_db_servers_list" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id +} + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + description = "my first avmc" + time_zone = "UTC" + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id =aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [ for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "CUSTOM_PREFERENCE" + days_of_week = ["MONDAY", "TUESDAY"] + hours_of_day = [4,16] + months = ["FEBRUARY","MAY","AUGUST","NOVEMBER"] + weeks_of_month =[2,4] + lead_time_in_weeks = 3 + } + tags = { + "env"= "dev" + } + +} + +`, exaInfraRes, odbNetRes, avmcDisplayName) + + return res +} + +func (autonomousVMClusterResourceTest) odbNet(odbNetName string) string { + networkRes := fmt.Sprintf(` + + +resource "aws_odb_network" "test" { + display_name = %[1]q + availability_zone_id = "use1-az6" + client_subnet_cidr = "10.2.0.0/24" + backup_subnet_cidr = "10.2.1.0/24" + s3_access = "DISABLED" + zero_etl_access = "DISABLED" +} + +`, odbNetName) + return networkRes +} + +func (autonomousVMClusterResourceTest) exaInfra(exaDisplayName string) string { + resource := fmt.Sprintf(` +resource "aws_odb_cloud_exadata_infrastructure" "test" { + display_name = "%[1]s" + shape = "Exadata.X9M" + storage_count = 3 + compute_count = 2 + availability_zone_id = "use1-az6" + customer_contacts_to_send_to_oci = ["abc@example.com"] + +} +`, exaDisplayName) + + return resource +} +func (autonomousVMClusterResourceTest) odbNetwork(odbNetDisplayName string) string { + return fmt.Sprintf(` + resource "aws_odb_network" "test" { + display_name = %[1]q + availability_zone_id = "use1-az6" + client_subnet_cidr = "10.2.0.0/24" + backup_subnet_cidr = "10.2.1.0/24" + s3_access = "DISABLED" + zero_etl_access = "DISABLED" + } +`, odbNetDisplayName) + +} + +func (autonomousVMClusterResourceTest) avmcBasic_hardCoded() string { + + avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) + + exaInfraRes := "exa_ji5quxxzn9" + odbNetRes := "odbnet_x37lc7bf7a" + + res := fmt.Sprintf(` + + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + cloud_exadata_infrastructure_id = %[1]q + odb_network_id = %[2]q + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [ "dbs_7ecm4wbjxy","dbs_uy5wmaqk6s"] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "NO_PREFERENCE" + days_of_week = [] + hours_of_day = [] + months = [] + weeks_of_month =[] + lead_time_in_weeks = 0 + } + +} + +`, exaInfraRes, odbNetRes, avmcDisplayName) + + return res +} diff --git a/internal/service/odb/service_package.go b/internal/service/odb/service_package.go new file mode 100644 index 000000000000..32a962a8ab63 --- /dev/null +++ b/internal/service/odb/service_package.go @@ -0,0 +1,21 @@ +//Copyright © 2025, Oracle and/or its affiliates. All rights reserved. + +package odb + +import ( + "context" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/odb" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func (p *servicePackage) NewClient(ctx context.Context, config map[string]any) (*odb.Client, error) { + cfg := *(config["aws_sdkv2_config"].(*aws.Config)) + + return odb.NewFromConfig(cfg, + odb.WithEndpointResolverV2(newEndpointResolverV2()), + withBaseEndpoint(config[names.AttrEndpoint].(string)), + func(o *odb.Options) { + }, + ), nil +} diff --git a/internal/service/odb/tags_gen.go b/internal/service/odb/tags_gen.go new file mode 100644 index 000000000000..3ae4f0f73d8e --- /dev/null +++ b/internal/service/odb/tags_gen.go @@ -0,0 +1,128 @@ +// Code generated by internal/generate/tags/main.go; DO NOT EDIT. +package odb + +import ( + "context" + + "github.com/YakDriver/smarterr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/odb" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/logging" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/types/option" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// listTags lists odb service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func listTags(ctx context.Context, conn *odb.Client, identifier string, optFns ...func(*odb.Options)) (tftags.KeyValueTags, error) { + input := odb.ListTagsForResourceInput{ + ResourceArn: aws.String(identifier), + } + + output, err := conn.ListTagsForResource(ctx, &input, optFns...) + + if err != nil { + return tftags.New(ctx, nil), smarterr.NewError(err) + } + + return keyValueTags(ctx, output.Tags), nil +} + +// ListTags lists odb service tags and set them in Context. +// It is called from outside this package. +func (p *servicePackage) ListTags(ctx context.Context, meta any, identifier string) error { + tags, err := listTags(ctx, meta.(*conns.AWSClient).ODBClient(ctx), identifier) + + if err != nil { + return smarterr.NewError(err) + } + + if inContext, ok := tftags.FromContext(ctx); ok { + inContext.TagsOut = option.Some(tags) + } + + return nil +} + +// map[string]string handling + +// svcTags returns odb service tags. +func svcTags(tags tftags.KeyValueTags) map[string]string { + return tags.Map() +} + +// keyValueTags creates tftags.KeyValueTags from odb service tags. +func keyValueTags(ctx context.Context, tags map[string]string) tftags.KeyValueTags { + return tftags.New(ctx, tags) +} + +// getTagsIn returns odb service tags from Context. +// nil is returned if there are no input tags. +func getTagsIn(ctx context.Context) map[string]string { + if inContext, ok := tftags.FromContext(ctx); ok { + if tags := svcTags(inContext.TagsIn.UnwrapOrDefault()); len(tags) > 0 { + return tags + } + } + + return nil +} + +// setTagsOut sets odb service tags in Context. +func setTagsOut(ctx context.Context, tags map[string]string) { + if inContext, ok := tftags.FromContext(ctx); ok { + inContext.TagsOut = option.Some(keyValueTags(ctx, tags)) + } +} + +// updateTags updates odb service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func updateTags(ctx context.Context, conn *odb.Client, identifier string, oldTagsMap, newTagsMap any, optFns ...func(*odb.Options)) error { + oldTags := tftags.New(ctx, oldTagsMap) + newTags := tftags.New(ctx, newTagsMap) + + ctx = tflog.SetField(ctx, logging.KeyResourceId, identifier) + + removedTags := oldTags.Removed(newTags) + removedTags = removedTags.IgnoreSystem(names.ODB) + if len(removedTags) > 0 { + input := odb.UntagResourceInput{ + ResourceArn: aws.String(identifier), + TagKeys: removedTags.Keys(), + } + + _, err := conn.UntagResource(ctx, &input, optFns...) + + if err != nil { + return smarterr.NewError(err) + } + } + + updatedTags := oldTags.Updated(newTags) + updatedTags = updatedTags.IgnoreSystem(names.ODB) + if len(updatedTags) > 0 { + input := odb.TagResourceInput{ + ResourceArn: aws.String(identifier), + Tags: svcTags(updatedTags), + } + + _, err := conn.TagResource(ctx, &input, optFns...) + + if err != nil { + return smarterr.NewError(err) + } + } + + return nil +} + +// UpdateTags updates odb service tags. +// It is called from outside this package. +func (p *servicePackage) UpdateTags(ctx context.Context, meta any, identifier string, oldTags, newTags any) error { + return updateTags(ctx, meta.(*conns.AWSClient).ODBClient(ctx), identifier, oldTags, newTags) +} diff --git a/names/data/names_data.hcl b/names/data/names_data.hcl index 6a83a3386cfa..ce6cc5f76534 100644 --- a/names/data/names_data.hcl +++ b/names/data/names_data.hcl @@ -9441,4 +9441,33 @@ service "evs" { provider_package_correct = "evs" doc_prefix = ["evs_"] brand = "Amazon" +} +service "odb" { + sdk { + id = "ODB" + arn_namespace = "odb" + } + names { + provider_name_upper = "ODB" + human_friendly = "Oracle Database@AWS" + } + endpoint_info { + endpoint_api_call = "ListGiVersions" + endpoint_region_overrides = { + "aws" = "us-east-1" + } + } + go_packages { + v1_package = "" + v2_package = "odb" + } + client{ + skip_client_generate = true + } + resource_prefix{ + correct = "aws_odb_" + } + provider_package_correct = "odb" + doc_prefix = ["odb_"] + brand = "AWS" } \ No newline at end of file From b105a878e8fa6ec6015cb45c95ede5d3df5dd4cf Mon Sep 17 00:00:00 2001 From: Asim Date: Mon, 11 Aug 2025 10:27:22 +0100 Subject: [PATCH 02/42] example of AVMC --- examples/odb/autonomous_vm_cluster.tf | 55 +++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 examples/odb/autonomous_vm_cluster.tf diff --git a/examples/odb/autonomous_vm_cluster.tf b/examples/odb/autonomous_vm_cluster.tf new file mode 100644 index 000000000000..540955f3a64a --- /dev/null +++ b/examples/odb/autonomous_vm_cluster.tf @@ -0,0 +1,55 @@ +# Copyright © 2025, Oracle and/or its affiliates. All rights reserved. + +# Autonomous VM Cluster with default maintenance window and minimum parameters +resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_minimum_parameters" { + cloud_exadata_infrastructure_id = "" # refer your exadata infra id + odb_network_id = "" # refer_your_odb_net_id + display_name = "Ofake-avmc-my_avmc" + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + # ids of db server. refer your exa infra. This is a manadatory fileld. Refer your cloud exadata infrastructure for db server id + db_servers = [""] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "NO_PREFERENCE" + days_of_week = [] + hours_of_day = [] + months = [] + weeks_of_month = [] + lead_time_in_weeks = 0 + } + +} + +# Autonomous VM Cluster with all parameters +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + description = "my first avmc" + time_zone = "UTC" + cloud_exadata_infrastructure_id = "" + odb_network_id = "" + display_name = "Ofake_my avmc" + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = ["", ""] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "CUSTOM_PREFERENCE" + days_of_week = ["MONDAY", "TUESDAY"] + hours_of_day = [4, 16] + months = ["FEBRUARY", "MAY", "AUGUST", "NOVEMBER"] + weeks_of_month = [2, 4] + lead_time_in_weeks = 3 + } + tags = { + "env" = "dev" + } + +} From d8424b1e024e74dc98c7ca73b38b910c063e6a47 Mon Sep 17 00:00:00 2001 From: Asim Date: Mon, 11 Aug 2025 10:38:58 +0100 Subject: [PATCH 03/42] change log added --- .changelog/43650.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changelog/43650.txt diff --git a/.changelog/43650.txt b/.changelog/43650.txt new file mode 100644 index 000000000000..a81513115f9a --- /dev/null +++ b/.changelog/43650.txt @@ -0,0 +1,7 @@ +```release-note:new-resource +aws_odb_cloud_autonomous_vm_cluster +``` + +```release-note:new-data-source +aws_odb_cloud_autonomous_vm_cluster +``` \ No newline at end of file From 3c2027be9b8d0c14dd705682ed69757a8ec294d8 Mon Sep 17 00:00:00 2001 From: Asim Date: Mon, 11 Aug 2025 11:04:51 +0100 Subject: [PATCH 04/42] fixed acc test for resource --- .../odb/cloud_autonomous_vm_cluster_test.go | 40 +------------------ 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go index 21068944bc09..28320013b677 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -178,7 +178,7 @@ func TestAccODBCloudAutonomousVmCluster_disappears(t *testing.T) { CheckDestroy: autonomousVMClusterResourceTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), Steps: []resource.TestStep{ { - Config: autonomousVMClusterResourceTestEntity.avmcBasic_hardCoded(), + Config: autonomousVMClusterResourceTestEntity.avmcBasic(), Check: resource.ComposeAggregateTestCheckFunc( autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &cloudautonomousvmcluster), acctest.CheckFrameworkResourceDisappears(ctx, acctest.Provider, tfodb.ResourceCloudAutonomousVMCluster, resourceName), @@ -493,41 +493,3 @@ func (autonomousVMClusterResourceTest) odbNetwork(odbNetDisplayName string) stri `, odbNetDisplayName) } - -func (autonomousVMClusterResourceTest) avmcBasic_hardCoded() string { - - avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) - - exaInfraRes := "exa_ji5quxxzn9" - odbNetRes := "odbnet_x37lc7bf7a" - - res := fmt.Sprintf(` - - -resource "aws_odb_cloud_autonomous_vm_cluster" "test" { - cloud_exadata_infrastructure_id = %[1]q - odb_network_id = %[2]q - display_name = %[3]q - autonomous_data_storage_size_in_tbs = 5 - memory_per_oracle_compute_unit_in_gbs = 2 - total_container_databases = 1 - cpu_core_count_per_node = 40 - license_model = "LICENSE_INCLUDED" - db_servers = [ "dbs_7ecm4wbjxy","dbs_uy5wmaqk6s"] - scan_listener_port_tls = 8561 - scan_listener_port_non_tls = 1024 - maintenance_window = { - preference = "NO_PREFERENCE" - days_of_week = [] - hours_of_day = [] - months = [] - weeks_of_month =[] - lead_time_in_weeks = 0 - } - -} - -`, exaInfraRes, odbNetRes, avmcDisplayName) - - return res -} From de96ecaed60a254c1524b9ff81fc78aa5187e1ca Mon Sep 17 00:00:00 2001 From: Asim Date: Mon, 11 Aug 2025 15:05:37 +0100 Subject: [PATCH 05/42] fixed acc test for resource --- .../service/odb/cloud_autonomous_vm_cluster_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go index 28320013b677..13f94ea8e8c9 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -475,6 +475,17 @@ resource "aws_odb_cloud_exadata_infrastructure" "test" { availability_zone_id = "use1-az6" customer_contacts_to_send_to_oci = ["abc@example.com"] + maintenance_window = { + custom_action_timeout_in_mins = 16 + days_of_week = [] + hours_of_day = [] + is_custom_action_timeout_enabled = true + lead_time_in_weeks = 0 + months = [] + patching_mode = "ROLLING" + preference = "NO_PREFERENCE" + weeks_of_month =[] + } } `, exaDisplayName) From f1be9e3d3f5f858a7f35d0646b48a7fd52ebf7e7 Mon Sep 17 00:00:00 2001 From: Asim Date: Mon, 25 Aug 2025 16:39:39 +0100 Subject: [PATCH 06/42] rebase with latest. refactored code according to feedback for exadata-infra PR. --- .../odb/cloud_autonomous_vm_cluster.go | 440 +++++------------- ...cloud_autonomous_vm_cluster_data_source.go | 234 +++------- ..._autonomous_vm_cluster_data_source_test.go | 8 +- .../odb/cloud_autonomous_vm_cluster_test.go | 17 +- internal/service/odb/service_package.go | 21 - internal/service/odb/service_package_gen.go | 25 +- names/data/names_data.hcl | 29 -- 7 files changed, 231 insertions(+), 543 deletions(-) delete mode 100644 internal/service/odb/service_package.go diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index 97fee679bdc9..e0eb88df779d 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -5,40 +5,36 @@ package odb import ( "context" "errors" - "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/float64planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int32planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" - "github.com/hashicorp/terraform-provider-aws/internal/enum" - tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/odb" odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/float64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int32planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" - "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/enum" "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" "github.com/hashicorp/terraform-provider-aws/internal/framework" "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" - "github.com/hashicorp/terraform-provider-aws/internal/sweep" - sweepfw "github.com/hashicorp/terraform-provider-aws/internal/sweep/framework" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -57,7 +53,6 @@ func newResourceCloudAutonomousVmCluster(_ context.Context) (resource.ResourceWi const ( ResNameCloudAutonomousVmCluster = "Cloud Autonomous Vm Cluster" - NotAvailableValues = "NOT_AVAILABLE" ) var ResourceCloudAutonomousVMCluster = newResourceCloudAutonomousVmCluster @@ -130,6 +125,7 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou }, "created_at": schema.StringAttribute{ Computed: true, + CustomType: timetypes.RFC3339Type{}, Description: "The date and time when the Autonomous VM cluster was created.", }, "data_storage_size_in_gbs": schema.Float64Attribute{ @@ -313,36 +309,14 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou Description: "The total number of Autonomous Container Databases that can be created with the allocated local storage. Changing this will force terraform to create new resource.", }, "time_ords_certificate_expires": schema.StringAttribute{ - Computed: true, + Computed: true, + CustomType: timetypes.RFC3339Type{}, }, "time_database_ssl_certificate_expires": schema.StringAttribute{ Computed: true, + CustomType: timetypes.RFC3339Type{}, Description: "The expiration date and time of the database SSL certificate.", }, - "maintenance_window": schema.ObjectAttribute{ - Required: true, - CustomType: fwtypes.NewObjectTypeOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel](ctx), - PlanModifiers: []planmodifier.Object{ - objectplanmodifier.RequiresReplace(), - }, - Description: "The maintenance window of the Autonomous VM cluster.", - AttributeTypes: map[string]attr.Type{ - "days_of_week": types.SetType{ - ElemType: fwtypes.StringEnumType[odbtypes.DayOfWeekName](), - }, - "hours_of_day": types.SetType{ - ElemType: types.Int32Type, - }, - "lead_time_in_weeks": types.Int32Type, - "months": types.SetType{ - ElemType: fwtypes.StringEnumType[odbtypes.MonthName](), - }, - "preference": fwtypes.StringEnumType[odbtypes.PreferenceType](), - "weeks_of_month": types.SetType{ - ElemType: types.Int32Type, - }, - }, - }, names.AttrTags: tftags.TagsAttribute(), names.AttrTagsAll: tftags.TagsAttributeComputedOnly(), }, @@ -352,13 +326,53 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou Update: true, Delete: true, }), + "maintenance_window": schema.ListNestedBlock{ + CustomType: fwtypes.NewListNestedObjectTypeOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel](ctx), + Validators: []validator.List{ + listvalidator.SizeAtMost(1), + listvalidator.SizeAtLeast(1), + }, + PlanModifiers: []planmodifier.List{ + listplanmodifier.RequiresReplace(), + }, + Description: "The maintenance window of the Autonomous VM cluster.", + + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "days_of_week": schema.SetAttribute{ + ElementType: fwtypes.NewObjectTypeOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel](ctx), + Optional: true, + Computed: true, + Description: "The day of week of the Autonomous VM cluster.", + }, + "months": schema.SetAttribute{ + ElementType: fwtypes.NewObjectTypeOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel](ctx), + Optional: true, + Computed: true, + Description: "The month of the Autonomous VM cluster.", + }, + "hours_of_day": schema.SetAttribute{ + ElementType: types.Int32Type, + Optional: true, + Computed: true, + }, + "lead_time_in_weeks": schema.Int32Attribute{ + Optional: true, + Computed: true, + }, + "preference": schema.StringAttribute{ + Required: true, + CustomType: fwtypes.StringEnumType[odbtypes.PreferenceType](), + }, + }, + }, + }, }, } } func (r *resourceCloudAutonomousVmCluster) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { conn := r.Meta().ODBClient(ctx) - var plan cloudAutonomousVmClusterResourceModel resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) if resp.Diagnostics.HasError() { @@ -366,9 +380,7 @@ func (r *resourceCloudAutonomousVmCluster) Create(ctx context.Context, req resou } input := odb.CreateCloudAutonomousVmClusterInput{ - ClientToken: aws.String(id.UniqueId()), - Tags: getTagsIn(ctx), - MaintenanceWindow: r.expandMaintenanceWindow(ctx, plan.MaintenanceWindow), + Tags: getTagsIn(ctx), } resp.Diagnostics.Append(flex.Expand(ctx, plan, &input)...) if resp.Diagnostics.HasError() { @@ -377,7 +389,6 @@ func (r *resourceCloudAutonomousVmCluster) Create(ctx context.Context, req resou out, err := conn.CreateCloudAutonomousVmCluster(ctx, &input) if err != nil { - resp.Diagnostics.AddError( create.ProblemStandardMessage(names.ODB, create.ErrActionCreating, ResNameCloudAutonomousVmCluster, plan.DisplayName.ValueString(), err), err.Error(), @@ -401,32 +412,11 @@ func (r *resourceCloudAutonomousVmCluster) Create(ctx context.Context, req resou ) return } - plan.CreatedAt = types.StringValue(createdAVMC.CreatedAt.Format(time.RFC3339)) - - if createdAVMC.TimeDatabaseSslCertificateExpires != nil { - plan.TimeDatabaseSslCertificateExpires = types.StringValue(createdAVMC.TimeDatabaseSslCertificateExpires.Format(time.RFC3339)) - } else { - plan.TimeDatabaseSslCertificateExpires = types.StringValue(NotAvailableValues) - } - - if createdAVMC.TimeOrdsCertificateExpires != nil { - plan.TimeOrdsCertificateExpires = types.StringValue(createdAVMC.TimeOrdsCertificateExpires.Format(time.RFC3339)) - } else { - plan.TimeOrdsCertificateExpires = types.StringValue(NotAvailableValues) - } - - if createdAVMC.MaintenanceWindow != nil { - plan.MaintenanceWindow = r.flattenMaintenanceWindow(ctx, createdAVMC.MaintenanceWindow) - } - resp.Diagnostics.Append(flex.Flatten(ctx, createdAVMC, &plan, - flex.WithIgnoredFieldNamesAppend("TimeOrdsCertificateExpires"), - flex.WithIgnoredFieldNamesAppend("TimeDatabaseSslCertificateExpires"))...) - + resp.Diagnostics.Append(flex.Flatten(ctx, createdAVMC, &plan)...) resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) } func (r *resourceCloudAutonomousVmCluster) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - conn := r.Meta().ODBClient(ctx) var state cloudAutonomousVmClusterResourceModel @@ -449,28 +439,10 @@ func (r *resourceCloudAutonomousVmCluster) Read(ctx context.Context, req resourc ) return } - - state.CreatedAt = types.StringValue(out.CreatedAt.Format(time.RFC3339)) - if out.TimeOrdsCertificateExpires != nil { - state.TimeOrdsCertificateExpires = types.StringValue(out.TimeOrdsCertificateExpires.Format(time.RFC3339)) - } else { - state.TimeOrdsCertificateExpires = types.StringValue(NotAvailableValues) - } - if out.TimeDatabaseSslCertificateExpires != nil { - state.TimeDatabaseSslCertificateExpires = types.StringValue(out.TimeDatabaseSslCertificateExpires.Format(time.RFC3339)) - } else { - state.TimeDatabaseSslCertificateExpires = types.StringValue(NotAvailableValues) - } - state.MaintenanceWindow = r.flattenMaintenanceWindow(ctx, out.MaintenanceWindow) - - resp.Diagnostics.Append(flex.Flatten(ctx, out, &state, - flex.WithIgnoredFieldNamesAppend("TimeOrdsCertificateExpires"), - flex.WithIgnoredFieldNamesAppend("TimeDatabaseSslCertificateExpires"))...) - + resp.Diagnostics.Append(flex.Flatten(ctx, out, &state)...) if resp.Diagnostics.HasError() { return } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) } @@ -494,24 +466,7 @@ func (r *resourceCloudAutonomousVmCluster) Update(ctx context.Context, req resou ) return } - plan.CreatedAt = types.StringValue(updatedAVMC.CreatedAt.Format(time.RFC3339)) - - if updatedAVMC.TimeDatabaseSslCertificateExpires != nil { - plan.TimeDatabaseSslCertificateExpires = types.StringValue(updatedAVMC.TimeDatabaseSslCertificateExpires.Format(time.RFC3339)) - } else { - plan.TimeDatabaseSslCertificateExpires = types.StringValue(NotAvailableValues) - } - - if updatedAVMC.TimeOrdsCertificateExpires != nil { - plan.TimeOrdsCertificateExpires = types.StringValue(updatedAVMC.TimeOrdsCertificateExpires.Format(time.RFC3339)) - } else { - plan.TimeOrdsCertificateExpires = types.StringValue(NotAvailableValues) - } - plan.MaintenanceWindow = r.flattenMaintenanceWindow(ctx, updatedAVMC.MaintenanceWindow) - resp.Diagnostics.Append(flex.Flatten(ctx, updatedAVMC, &plan, - flex.WithIgnoredFieldNamesAppend("TimeOrdsCertificateExpires"), - flex.WithIgnoredFieldNamesAppend("TimeDatabaseSslCertificateExpires"))...) - + resp.Diagnostics.Append(flex.Flatten(ctx, updatedAVMC, &plan)...) if resp.Diagnostics.HasError() { return } @@ -645,222 +600,75 @@ func FindCloudAutonomousVmClusterByID(ctx context.Context, conn *odb.Client, id return out.CloudAutonomousVmCluster, nil } -// TIP: ==== SWEEPERS ==== -// When acceptance testing resources, interrupted or failed tests may -// leave behind orphaned resources in an account. To facilitate cleaning -// up lingering resources, each resource implementation should include -// a corresponding "sweeper" function. -// -// The sweeper function lists all resources of a given type and sets the -// appropriate identifers required to delete the resource via the Delete -// method implemented above. -// -// Once the sweeper function is implemented, register it in sweeper.go -// as follows: -// -// awsv2.Register("aws_odb_cloud_autonomous_vm_cluster", sweepCloudAutonomousVmClusters) -// -// See more: -// https://hashicorp.github.io/terraform-provider-aws/running-and-writing-acceptance-tests/#acceptance-test-sweepers -func sweepCloudAutonomousVmClusters(ctx context.Context, client *conns.AWSClient) ([]sweep.Sweepable, error) { - input := odb.ListCloudAutonomousVmClustersInput{} - conn := client.ODBClient(ctx) - var sweepResources []sweep.Sweepable - - pages := odb.NewListCloudAutonomousVmClustersPaginator(conn, &input) - for pages.HasMorePages() { - page, err := pages.NextPage(ctx) - if err != nil { - return nil, err - } - - for _, v := range page.CloudAutonomousVmClusters { - sweepResources = append(sweepResources, sweepfw.NewSweepResource(newResourceCloudAutonomousVmCluster, client, - sweepfw.NewAttribute(names.AttrID, aws.ToString(v.CloudAutonomousVmClusterId))), - ) - } - } - - return sweepResources, nil -} - -func (r *resourceCloudAutonomousVmCluster) expandMaintenanceWindow(ctx context.Context, avmcMaintenanceWindowFwTypesObj fwtypes.ObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel]) *odbtypes.MaintenanceWindow { - var avmcMaintenanceWindowResource cloudAutonomousVmClusterMaintenanceWindowResourceModel - - avmcMaintenanceWindowFwTypesObj.As(ctx, &avmcMaintenanceWindowResource, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - }) - - var daysOfWeekNames []odbtypes.DayOfWeekName - avmcMaintenanceWindowResource.DaysOfWeek.ElementsAs(ctx, &daysOfWeekNames, false) - daysOfWeek := make([]odbtypes.DayOfWeek, 0, len(daysOfWeekNames)) - - for _, dayOfWeek := range daysOfWeekNames { - daysOfWeek = append(daysOfWeek, odbtypes.DayOfWeek{ - Name: dayOfWeek, - }) - } - - var hoursOfTheDay []int32 - avmcMaintenanceWindowResource.HoursOfDay.ElementsAs(ctx, &hoursOfTheDay, false) - - var monthNames []odbtypes.MonthName - avmcMaintenanceWindowResource.Months.ElementsAs(ctx, &monthNames, false) - months := make([]odbtypes.Month, 0, len(monthNames)) - for _, month := range monthNames { - months = append(months, odbtypes.Month{ - Name: month, - }) - } - - var weeksOfMonth []int32 - avmcMaintenanceWindowResource.WeeksOfMonth.ElementsAs(ctx, &weeksOfMonth, false) - - odbTypeMW := odbtypes.MaintenanceWindow{ - DaysOfWeek: daysOfWeek, - HoursOfDay: hoursOfTheDay, - LeadTimeInWeeks: avmcMaintenanceWindowResource.LeadTimeInWeeks.ValueInt32Pointer(), - Months: months, - Preference: avmcMaintenanceWindowResource.Preference.ValueEnum(), - WeeksOfMonth: weeksOfMonth, - } - if len(odbTypeMW.DaysOfWeek) == 0 { - odbTypeMW.DaysOfWeek = nil - } - if len(odbTypeMW.HoursOfDay) == 0 { - odbTypeMW.HoursOfDay = nil - } - if len(odbTypeMW.Months) == 0 { - odbTypeMW.Months = nil - } - if len(odbTypeMW.WeeksOfMonth) == 0 { - odbTypeMW.WeeksOfMonth = nil - } - if *odbTypeMW.LeadTimeInWeeks == 0 { - odbTypeMW.LeadTimeInWeeks = nil - } - return &odbTypeMW +type cloudAutonomousVmClusterResourceModel struct { + framework.WithRegionModel + CloudAutonomousVmClusterArn types.String `tfsdk:"arn"` + CloudAutonomousVmClusterId types.String `tfsdk:"id"` + CloudExadataInfrastructureId types.String `tfsdk:"cloud_exadata_infrastructure_id"` + AutonomousDataStoragePercentage types.Float32 `tfsdk:"autonomous_data_storage_percentage"` + AutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"autonomous_data_storage_size_in_tbs"` + AvailableAutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"available_autonomous_data_storage_size_in_tbs"` + AvailableContainerDatabases types.Int32 `tfsdk:"available_container_databases"` + AvailableCpus types.Float32 `tfsdk:"available_cpus"` + ComputeModel fwtypes.StringEnum[odbtypes.ComputeModel] `tfsdk:"compute_model"` + CpuCoreCount types.Int32 `tfsdk:"cpu_core_count"` + CpuCoreCountPerNode types.Int32 `tfsdk:"cpu_core_count_per_node"` + CpuPercentage types.Float32 `tfsdk:"cpu_percentage"` + CreatedAt timetypes.RFC3339 `tfsdk:"created_at" ` + DataStorageSizeInGBs types.Float64 `tfsdk:"data_storage_size_in_gbs"` + DataStorageSizeInTBs types.Float64 `tfsdk:"data_storage_size_in_tbs"` + DbNodeStorageSizeInGBs types.Int32 `tfsdk:"odb_node_storage_size_in_gbs"` + DbServers fwtypes.SetValueOf[types.String] `tfsdk:"db_servers"` + Description types.String `tfsdk:"description"` + DisplayName types.String `tfsdk:"display_name"` + Domain types.String `tfsdk:"domain"` + ExadataStorageInTBsLowestScaledValue types.Float64 `tfsdk:"exadata_storage_in_tbs_lowest_scaled_value"` + Hostname types.String `tfsdk:"hostname"` + IsMtlsEnabledVmCluster types.Bool `tfsdk:"is_mtls_enabled_vm_cluster"` + LicenseModel fwtypes.StringEnum[odbtypes.LicenseModel] `tfsdk:"license_model"` + MaxAcdsLowestScaledValue types.Int32 `tfsdk:"max_acds_lowest_scaled_value"` + MemoryPerOracleComputeUnitInGBs types.Int32 `tfsdk:"memory_per_oracle_compute_unit_in_gbs"` + MemorySizeInGBs types.Int32 `tfsdk:"memory_size_in_gbs"` + NodeCount types.Int32 `tfsdk:"node_count"` + NonProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"non_provisionable_autonomous_container_databases"` + OciResourceAnchorName types.String `tfsdk:"oci_resource_anchor_name"` + OciUrl types.String `tfsdk:"oci_url"` + Ocid types.String `tfsdk:"ocid"` + OdbNetworkId types.String `tfsdk:"odb_network_id"` + PercentProgress types.Float32 `tfsdk:"percent_progress"` + ProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"provisionable_autonomous_container_databases"` + ProvisionedAutonomousContainerDatabases types.Int32 `tfsdk:"provisioned_autonomous_container_databases"` + ProvisionedCpus types.Float32 `tfsdk:"provisioned_cpus"` + ReclaimableCpus types.Float32 `tfsdk:"reclaimable_cpus"` + ReservedCpus types.Float32 `tfsdk:"reserved_cpus"` + ScanListenerPortNonTls types.Int32 `tfsdk:"scan_listener_port_non_tls"` + ScanListenerPortTls types.Int32 `tfsdk:"scan_listener_port_tls"` + Shape types.String `tfsdk:"shape"` + Status fwtypes.StringEnum[odbtypes.ResourceStatus] `tfsdk:"status"` + StatusReason types.String `tfsdk:"status_reason"` + TimeZone types.String `tfsdk:"time_zone"` + TotalContainerDatabases types.Int32 `tfsdk:"total_container_databases"` + Timeouts timeouts.Value `tfsdk:"timeouts"` + Tags tftags.Map `tfsdk:"tags"` + TagsAll tftags.Map `tfsdk:"tags_all"` + TimeOrdsCertificateExpires timetypes.RFC3339 `tfsdk:"time_ords_certificate_expires"` + TimeDatabaseSslCertificateExpires timetypes.RFC3339 `tfsdk:"time_database_ssl_certificate_expires"` + MaintenanceWindow fwtypes.ListNestedObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"maintenance_window" ` } -func (r *resourceCloudAutonomousVmCluster) flattenMaintenanceWindow(ctx context.Context, avmcMW *odbtypes.MaintenanceWindow) fwtypes.ObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel] { - //days of week - daysOfWeek := make([]attr.Value, 0, len(avmcMW.DaysOfWeek)) - for _, dayOfWeek := range avmcMW.DaysOfWeek { - dayOfWeekStringValue := fwtypes.StringEnumValue(dayOfWeek.Name).StringValue - daysOfWeek = append(daysOfWeek, dayOfWeekStringValue) - } - setValueOfDaysOfWeek, _ := basetypes.NewSetValue(types.StringType, daysOfWeek) - daysOfWeekRead := fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.DayOfWeekName]]{ - SetValue: setValueOfDaysOfWeek, - } - //hours of the day - hoursOfTheDay := make([]attr.Value, 0, len(avmcMW.HoursOfDay)) - for _, hourOfTheDay := range avmcMW.HoursOfDay { - daysOfWeekInt32Value := types.Int32Value(hourOfTheDay) - hoursOfTheDay = append(hoursOfTheDay, daysOfWeekInt32Value) - } - setValuesOfHoursOfTheDay, _ := basetypes.NewSetValue(types.Int32Type, hoursOfTheDay) - hoursOfTheDayRead := fwtypes.SetValueOf[types.Int32]{ - SetValue: setValuesOfHoursOfTheDay, - } - //monts - months := make([]attr.Value, 0, len(avmcMW.Months)) - for _, month := range avmcMW.Months { - monthStringValue := fwtypes.StringEnumValue(month.Name).StringValue - months = append(months, monthStringValue) - } - setValuesOfMonth, _ := basetypes.NewSetValue(types.StringType, months) - monthsRead := fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.MonthName]]{ - SetValue: setValuesOfMonth, - } - //weeks of month - weeksOfMonth := make([]attr.Value, 0, len(avmcMW.WeeksOfMonth)) - for _, weekOfMonth := range avmcMW.WeeksOfMonth { - weeksOfMonthInt32Value := types.Int32Value(weekOfMonth) - weeksOfMonth = append(weeksOfMonth, weeksOfMonthInt32Value) - } - setValuesOfWeekOfMonth, _ := basetypes.NewSetValue(types.Int32Type, weeksOfMonth) - weeksOfMonthRead := fwtypes.SetValueOf[types.Int32]{ - SetValue: setValuesOfWeekOfMonth, - } - - computedMW := cloudAutonomousVmClusterMaintenanceWindowResourceModel{ - DaysOfWeek: daysOfWeekRead, - HoursOfDay: hoursOfTheDayRead, - LeadTimeInWeeks: types.Int32PointerValue(avmcMW.LeadTimeInWeeks), - Months: monthsRead, - Preference: fwtypes.StringEnumValue(avmcMW.Preference), - WeeksOfMonth: weeksOfMonthRead, - } - if avmcMW.LeadTimeInWeeks == nil { - computedMW.LeadTimeInWeeks = types.Int32Value(0) - } - result, _ := fwtypes.NewObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel](ctx, &computedMW) - return result +type cloudAutonomousVmClusterMaintenanceWindowResourceModel struct { + DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"days_of_week"` + HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` + LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` + Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"months"` + Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` + WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` } -type cloudAutonomousVmClusterResourceModel struct { - framework.WithRegionModel - CloudAutonomousVmClusterArn types.String `tfsdk:"arn"` - CloudAutonomousVmClusterId types.String `tfsdk:"id"` - CloudExadataInfrastructureId types.String `tfsdk:"cloud_exadata_infrastructure_id"` - AutonomousDataStoragePercentage types.Float32 `tfsdk:"autonomous_data_storage_percentage"` - AutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"autonomous_data_storage_size_in_tbs"` - AvailableAutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"available_autonomous_data_storage_size_in_tbs"` - AvailableContainerDatabases types.Int32 `tfsdk:"available_container_databases"` - AvailableCpus types.Float32 `tfsdk:"available_cpus"` - ComputeModel fwtypes.StringEnum[odbtypes.ComputeModel] `tfsdk:"compute_model"` - CpuCoreCount types.Int32 `tfsdk:"cpu_core_count"` - CpuCoreCountPerNode types.Int32 `tfsdk:"cpu_core_count_per_node"` - CpuPercentage types.Float32 `tfsdk:"cpu_percentage"` - CreatedAt types.String `tfsdk:"created_at" autoflex:",noflatten"` - DataStorageSizeInGBs types.Float64 `tfsdk:"data_storage_size_in_gbs"` - DataStorageSizeInTBs types.Float64 `tfsdk:"data_storage_size_in_tbs"` - DbNodeStorageSizeInGBs types.Int32 `tfsdk:"odb_node_storage_size_in_gbs"` - DbServers fwtypes.SetValueOf[types.String] `tfsdk:"db_servers"` - Description types.String `tfsdk:"description"` - DisplayName types.String `tfsdk:"display_name"` - Domain types.String `tfsdk:"domain"` - ExadataStorageInTBsLowestScaledValue types.Float64 `tfsdk:"exadata_storage_in_tbs_lowest_scaled_value"` - Hostname types.String `tfsdk:"hostname"` - IsMtlsEnabledVmCluster types.Bool `tfsdk:"is_mtls_enabled_vm_cluster"` - LicenseModel fwtypes.StringEnum[odbtypes.LicenseModel] `tfsdk:"license_model"` - MaxAcdsLowestScaledValue types.Int32 `tfsdk:"max_acds_lowest_scaled_value"` - MemoryPerOracleComputeUnitInGBs types.Int32 `tfsdk:"memory_per_oracle_compute_unit_in_gbs"` - MemorySizeInGBs types.Int32 `tfsdk:"memory_size_in_gbs"` - NodeCount types.Int32 `tfsdk:"node_count"` - NonProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"non_provisionable_autonomous_container_databases"` - OciResourceAnchorName types.String `tfsdk:"oci_resource_anchor_name"` - OciUrl types.String `tfsdk:"oci_url"` - Ocid types.String `tfsdk:"ocid"` - OdbNetworkId types.String `tfsdk:"odb_network_id"` - PercentProgress types.Float32 `tfsdk:"percent_progress"` - ProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"provisionable_autonomous_container_databases"` - ProvisionedAutonomousContainerDatabases types.Int32 `tfsdk:"provisioned_autonomous_container_databases"` - ProvisionedCpus types.Float32 `tfsdk:"provisioned_cpus"` - ReclaimableCpus types.Float32 `tfsdk:"reclaimable_cpus"` - ReservedCpus types.Float32 `tfsdk:"reserved_cpus"` - ScanListenerPortNonTls types.Int32 `tfsdk:"scan_listener_port_non_tls"` - ScanListenerPortTls types.Int32 `tfsdk:"scan_listener_port_tls"` - Shape types.String `tfsdk:"shape"` - Status fwtypes.StringEnum[odbtypes.ResourceStatus] `tfsdk:"status"` - StatusReason types.String `tfsdk:"status_reason"` - TimeZone types.String `tfsdk:"time_zone"` - TotalContainerDatabases types.Int32 `tfsdk:"total_container_databases"` - Timeouts timeouts.Value `tfsdk:"timeouts"` - Tags tftags.Map `tfsdk:"tags"` - TagsAll tftags.Map `tfsdk:"tags_all"` - TimeOrdsCertificateExpires types.String `tfsdk:"time_ords_certificate_expires"` - TimeDatabaseSslCertificateExpires types.String `tfsdk:"time_database_ssl_certificate_expires"` - MaintenanceWindow fwtypes.ObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"maintenance_window" autoflex:"-"` +type dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel struct { + Name fwtypes.StringEnum[odbtypes.DayOfWeekName] `tfsdk:"name"` } -type cloudAutonomousVmClusterMaintenanceWindowResourceModel struct { - DaysOfWeek fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.DayOfWeekName]] `tfsdk:"days_of_week"` - HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` - LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` - Months fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.MonthName]] `tfsdk:"months"` - Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` - WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` +type monthNameAutonomousVmClusterMaintenanceWindowResourceModel struct { + Name fwtypes.StringEnum[odbtypes.MonthName] `tfsdk:"name"` } diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go index ce561fff9d4d..20d11239924c 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go @@ -4,14 +4,10 @@ package odb import ( "context" - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" - tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" - "time" "github.com/aws/aws-sdk-go-v2/service/odb" odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" - + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" @@ -19,11 +15,13 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/framework" "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/names" ) // Function annotations are used for datasource registration to the Provider. DO NOT EDIT. // @FrameworkDataSource("aws_odb_cloud_autonomous_vm_cluster", name="Cloud Autonomous Vm Cluster") +// @Tags(identifierAttribute="arn") func newDataSourceCloudAutonomousVmCluster(context.Context) (datasource.DataSourceWithConfigure, error) { return &dataSourceCloudAutonomousVmCluster{}, nil } @@ -91,6 +89,7 @@ func (d *dataSourceCloudAutonomousVmCluster) Schema(ctx context.Context, req dat }, "created_at": schema.StringAttribute{ Computed: true, + CustomType: timetypes.RFC3339Type{}, Description: "The date and time when the Autonomous VM cluster was created.", }, "data_storage_size_in_gbs": schema.Float64Attribute{ @@ -212,21 +211,23 @@ func (d *dataSourceCloudAutonomousVmCluster) Schema(ctx context.Context, req dat Computed: true, Description: "The shape of the Exadata infrastructure for the Autonomous VM cluster.", }, - "status": schema.StringAttribute{ + names.AttrStatus: schema.StringAttribute{ CustomType: status, Computed: true, Description: "The status of the Autonomous VM cluster.", }, - "status_reason": schema.StringAttribute{ + names.AttrStatusReason: schema.StringAttribute{ Computed: true, Description: "Additional information about the current status of the Autonomous VM cluster.", }, "time_database_ssl_certificate_expires": schema.StringAttribute{ Computed: true, + CustomType: timetypes.RFC3339Type{}, Description: "The expiration date and time of the database SSL certificate.", }, "time_ords_certificate_expires": schema.StringAttribute{ Computed: true, + CustomType: timetypes.RFC3339Type{}, Description: "The expiration date and time of the Oracle REST Data Services (ORDS)certificate .", }, "time_zone": schema.StringAttribute{ @@ -237,33 +238,16 @@ func (d *dataSourceCloudAutonomousVmCluster) Schema(ctx context.Context, req dat Computed: true, }, names.AttrTags: tftags.TagsAttributeComputedOnly(), - "maintenance_window": schema.ObjectAttribute{ + "maintenance_window": schema.ListAttribute{ Computed: true, - CustomType: fwtypes.NewObjectTypeOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel](ctx), + CustomType: fwtypes.NewListNestedObjectTypeOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel](ctx), Description: "The maintenance window for the Autonomous VM cluster.", - AttributeTypes: map[string]attr.Type{ - "days_of_week": types.SetType{ - ElemType: fwtypes.StringEnumType[odbtypes.DayOfWeekName](), - }, - "hours_of_day": types.SetType{ - ElemType: types.Int32Type, - }, - "lead_time_in_weeks": types.Int32Type, - "months": types.SetType{ - ElemType: fwtypes.StringEnumType[odbtypes.MonthName](), - }, - "preference": fwtypes.StringEnumType[odbtypes.PreferenceType](), - "weeks_of_month": types.SetType{ - ElemType: types.Int32Type, - }, - }, }, }, } } func (d *dataSourceCloudAutonomousVmCluster) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - conn := d.Meta().ODBClient(ctx) var data cloudAutonomousVmClusterDataSourceModel @@ -283,31 +267,6 @@ func (d *dataSourceCloudAutonomousVmCluster) Read(ctx context.Context, req datas ) return } - data.CreatedAt = types.StringValue(out.CloudAutonomousVmCluster.CreatedAt.Format(time.RFC3339)) - if out.CloudAutonomousVmCluster.TimeOrdsCertificateExpires != nil { - data.TimeOrdsCertificateExpires = types.StringValue(out.CloudAutonomousVmCluster.TimeOrdsCertificateExpires.Format(time.RFC3339)) - } else { - data.TimeOrdsCertificateExpires = types.StringValue(NotAvailableValues) - } - if out.CloudAutonomousVmCluster.TimeDatabaseSslCertificateExpires != nil { - data.TimeDatabaseSslCertificateExpires = types.StringValue(out.CloudAutonomousVmCluster.TimeDatabaseSslCertificateExpires.Format(time.RFC3339)) - } else { - data.TimeDatabaseSslCertificateExpires = types.StringValue(NotAvailableValues) - } - tagsRead, err := listTags(ctx, conn, *out.CloudAutonomousVmCluster.CloudAutonomousVmClusterArn) - if err != nil { - resp.Diagnostics.AddError( - create.ProblemStandardMessage(names.ODB, create.ErrActionReading, DSNameCloudAutonomousVmCluster, data.CloudAutonomousVmClusterId.ValueString(), err), - err.Error(), - ) - return - } - if tagsRead != nil { - data.Tags = tftags.FlattenStringValueMap(ctx, tagsRead.Map()) - } - - data.MaintenanceWindow = d.flattenMaintenanceWindow(ctx, out.CloudAutonomousVmCluster.MaintenanceWindow) - resp.Diagnostics.Append(flex.Flatten(ctx, out.CloudAutonomousVmCluster, &data)...) if resp.Diagnostics.HasError() { return @@ -316,118 +275,71 @@ func (d *dataSourceCloudAutonomousVmCluster) Read(ctx context.Context, req datas resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } -func (d *dataSourceCloudAutonomousVmCluster) flattenMaintenanceWindow(ctx context.Context, avmcMW *odbtypes.MaintenanceWindow) fwtypes.ObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel] { - //days of week - daysOfWeek := make([]attr.Value, 0, len(avmcMW.DaysOfWeek)) - for _, dayOfWeek := range avmcMW.DaysOfWeek { - dayOfWeekStringValue := fwtypes.StringEnumValue(dayOfWeek.Name).StringValue - daysOfWeek = append(daysOfWeek, dayOfWeekStringValue) - } - setValueOfDaysOfWeek, _ := basetypes.NewSetValue(types.StringType, daysOfWeek) - daysOfWeekRead := fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.DayOfWeekName]]{ - SetValue: setValueOfDaysOfWeek, - } - //hours of the day - hoursOfTheDay := make([]attr.Value, 0, len(avmcMW.HoursOfDay)) - for _, hourOfTheDay := range avmcMW.HoursOfDay { - daysOfWeekInt32Value := types.Int32Value(hourOfTheDay) - hoursOfTheDay = append(hoursOfTheDay, daysOfWeekInt32Value) - } - setValuesOfHoursOfTheDay, _ := basetypes.NewSetValue(types.Int32Type, hoursOfTheDay) - hoursOfTheDayRead := fwtypes.SetValueOf[types.Int32]{ - SetValue: setValuesOfHoursOfTheDay, - } - //monts - months := make([]attr.Value, 0, len(avmcMW.Months)) - for _, month := range avmcMW.Months { - monthStringValue := fwtypes.StringEnumValue(month.Name).StringValue - months = append(months, monthStringValue) - } - setValuesOfMonth, _ := basetypes.NewSetValue(types.StringType, months) - monthsRead := fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.MonthName]]{ - SetValue: setValuesOfMonth, - } - //weeks of month - weeksOfMonth := make([]attr.Value, 0, len(avmcMW.WeeksOfMonth)) - for _, weekOfMonth := range avmcMW.WeeksOfMonth { - weeksOfMonthInt32Value := types.Int32Value(weekOfMonth) - weeksOfMonth = append(weeksOfMonth, weeksOfMonthInt32Value) - } - setValuesOfWeekOfMonth, _ := basetypes.NewSetValue(types.Int32Type, weeksOfMonth) - weeksOfMonthRead := fwtypes.SetValueOf[types.Int32]{ - SetValue: setValuesOfWeekOfMonth, - } - - computedMW := cloudAutonomousVmClusterMaintenanceWindowDataSourceModel{ - DaysOfWeek: daysOfWeekRead, - HoursOfDay: hoursOfTheDayRead, - LeadTimeInWeeks: types.Int32PointerValue(avmcMW.LeadTimeInWeeks), - Months: monthsRead, - Preference: fwtypes.StringEnumValue(avmcMW.Preference), - WeeksOfMonth: weeksOfMonthRead, - } - result, _ := fwtypes.NewObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel](ctx, &computedMW) - return result -} - type cloudAutonomousVmClusterDataSourceModel struct { framework.WithRegionModel - CloudAutonomousVmClusterArn types.String `tfsdk:"arn"` - CloudAutonomousVmClusterId types.String `tfsdk:"id"` - CloudExadataInfrastructureId types.String `tfsdk:"cloud_exadata_infrastructure_id"` - AutonomousDataStoragePercentage types.Float32 `tfsdk:"autonomous_data_storage_percentage"` - AutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"autonomous_data_storage_size_in_tbs"` - AvailableAutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"available_autonomous_data_storage_size_in_tbs"` - AvailableContainerDatabases types.Int32 `tfsdk:"available_container_databases"` - AvailableCpus types.Float32 `tfsdk:"available_cpus"` - ComputeModel fwtypes.StringEnum[odbtypes.ComputeModel] `tfsdk:"compute_model"` - CpuCoreCount types.Int32 `tfsdk:"cpu_core_count"` - CpuCoreCountPerNode types.Int32 `tfsdk:"cpu_core_count_per_node"` - CpuPercentage types.Float32 `tfsdk:"cpu_percentage"` - CreatedAt types.String `tfsdk:"created_at" autoflex:",noflatten"` - DataStorageSizeInGBs types.Float64 `tfsdk:"data_storage_size_in_gbs"` - DataStorageSizeInTBs types.Float64 `tfsdk:"data_storage_size_in_tbs"` - DbNodeStorageSizeInGBs types.Int32 `tfsdk:"odb_node_storage_size_in_gbs"` - DbServers fwtypes.SetValueOf[types.String] `tfsdk:"db_servers"` - Description types.String `tfsdk:"description"` - DisplayName types.String `tfsdk:"display_name"` - Domain types.String `tfsdk:"domain"` - ExadataStorageInTBsLowestScaledValue types.Float64 `tfsdk:"exadata_storage_in_tbs_lowest_scaled_value"` - Hostname types.String `tfsdk:"hostname"` - IsMtlsEnabledVmCluster types.Bool `tfsdk:"is_mtls_enabled_vm_cluster"` - LicenseModel fwtypes.StringEnum[odbtypes.LicenseModel] `tfsdk:"license_model"` - MaxAcdsLowestScaledValue types.Int32 `tfsdk:"max_acds_lowest_scaled_value"` - MemoryPerOracleComputeUnitInGBs types.Int32 `tfsdk:"memory_per_oracle_compute_unit_in_gbs"` - MemorySizeInGBs types.Int32 `tfsdk:"memory_size_in_gbs"` - NodeCount types.Int32 `tfsdk:"node_count"` - NonProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"non_provisionable_autonomous_container_databases"` - OciResourceAnchorName types.String `tfsdk:"oci_resource_anchor_name"` - OciUrl types.String `tfsdk:"oci_url"` - Ocid types.String `tfsdk:"ocid"` - OdbNetworkId types.String `tfsdk:"odb_network_id"` - PercentProgress types.Float32 `tfsdk:"percent_progress"` - ProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"provisionable_autonomous_container_databases"` - ProvisionedAutonomousContainerDatabases types.Int32 `tfsdk:"provisioned_autonomous_container_databases"` - ProvisionedCpus types.Float32 `tfsdk:"provisioned_cpus"` - ReclaimableCpus types.Float32 `tfsdk:"reclaimable_cpus"` - ReservedCpus types.Float32 `tfsdk:"reserved_cpus"` - ScanListenerPortNonTls types.Int32 `tfsdk:"scan_listener_port_non_tls"` - ScanListenerPortTls types.Int32 `tfsdk:"scan_listener_port_tls"` - Shape types.String `tfsdk:"shape"` - Status fwtypes.StringEnum[odbtypes.ResourceStatus] `tfsdk:"status"` - StatusReason types.String `tfsdk:"status_reason"` - TimeDatabaseSslCertificateExpires types.String `tfsdk:"time_database_ssl_certificate_expires" autoflex:",noflatten"` - TimeOrdsCertificateExpires types.String `tfsdk:"time_ords_certificate_expires" autoflex:",noflatten"` - TimeZone types.String `tfsdk:"time_zone"` - TotalContainerDatabases types.Int32 `tfsdk:"total_container_databases"` - MaintenanceWindow fwtypes.ObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"maintenance_window" autoflex:",noflatten"` - Tags tftags.Map `tfsdk:"tags"` + CloudAutonomousVmClusterArn types.String `tfsdk:"arn"` + CloudAutonomousVmClusterId types.String `tfsdk:"id"` + CloudExadataInfrastructureId types.String `tfsdk:"cloud_exadata_infrastructure_id"` + AutonomousDataStoragePercentage types.Float32 `tfsdk:"autonomous_data_storage_percentage"` + AutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"autonomous_data_storage_size_in_tbs"` + AvailableAutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"available_autonomous_data_storage_size_in_tbs"` + AvailableContainerDatabases types.Int32 `tfsdk:"available_container_databases"` + AvailableCpus types.Float32 `tfsdk:"available_cpus"` + ComputeModel fwtypes.StringEnum[odbtypes.ComputeModel] `tfsdk:"compute_model"` + CpuCoreCount types.Int32 `tfsdk:"cpu_core_count"` + CpuCoreCountPerNode types.Int32 `tfsdk:"cpu_core_count_per_node"` + CpuPercentage types.Float32 `tfsdk:"cpu_percentage"` + CreatedAt timetypes.RFC3339 `tfsdk:"created_at" ` + DataStorageSizeInGBs types.Float64 `tfsdk:"data_storage_size_in_gbs"` + DataStorageSizeInTBs types.Float64 `tfsdk:"data_storage_size_in_tbs"` + DbNodeStorageSizeInGBs types.Int32 `tfsdk:"odb_node_storage_size_in_gbs"` + DbServers fwtypes.SetValueOf[types.String] `tfsdk:"db_servers"` + Description types.String `tfsdk:"description"` + DisplayName types.String `tfsdk:"display_name"` + Domain types.String `tfsdk:"domain"` + ExadataStorageInTBsLowestScaledValue types.Float64 `tfsdk:"exadata_storage_in_tbs_lowest_scaled_value"` + Hostname types.String `tfsdk:"hostname"` + IsMtlsEnabledVmCluster types.Bool `tfsdk:"is_mtls_enabled_vm_cluster"` + LicenseModel fwtypes.StringEnum[odbtypes.LicenseModel] `tfsdk:"license_model"` + MaxAcdsLowestScaledValue types.Int32 `tfsdk:"max_acds_lowest_scaled_value"` + MemoryPerOracleComputeUnitInGBs types.Int32 `tfsdk:"memory_per_oracle_compute_unit_in_gbs"` + MemorySizeInGBs types.Int32 `tfsdk:"memory_size_in_gbs"` + NodeCount types.Int32 `tfsdk:"node_count"` + NonProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"non_provisionable_autonomous_container_databases"` + OciResourceAnchorName types.String `tfsdk:"oci_resource_anchor_name"` + OciUrl types.String `tfsdk:"oci_url"` + Ocid types.String `tfsdk:"ocid"` + OdbNetworkId types.String `tfsdk:"odb_network_id"` + PercentProgress types.Float32 `tfsdk:"percent_progress"` + ProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"provisionable_autonomous_container_databases"` + ProvisionedAutonomousContainerDatabases types.Int32 `tfsdk:"provisioned_autonomous_container_databases"` + ProvisionedCpus types.Float32 `tfsdk:"provisioned_cpus"` + ReclaimableCpus types.Float32 `tfsdk:"reclaimable_cpus"` + ReservedCpus types.Float32 `tfsdk:"reserved_cpus"` + ScanListenerPortNonTls types.Int32 `tfsdk:"scan_listener_port_non_tls"` + ScanListenerPortTls types.Int32 `tfsdk:"scan_listener_port_tls"` + Shape types.String `tfsdk:"shape"` + Status fwtypes.StringEnum[odbtypes.ResourceStatus] `tfsdk:"status"` + StatusReason types.String `tfsdk:"status_reason"` + TimeDatabaseSslCertificateExpires timetypes.RFC3339 `tfsdk:"time_database_ssl_certificate_expires"` + TimeOrdsCertificateExpires timetypes.RFC3339 `tfsdk:"time_ords_certificate_expires" ` + TimeZone types.String `tfsdk:"time_zone"` + TotalContainerDatabases types.Int32 `tfsdk:"total_container_databases"` + MaintenanceWindow fwtypes.ListNestedObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"maintenance_window" ` + Tags tftags.Map `tfsdk:"tags"` } type cloudAutonomousVmClusterMaintenanceWindowDataSourceModel struct { - DaysOfWeek fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.DayOfWeekName]] `tfsdk:"days_of_week"` - HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` - LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` - Months fwtypes.SetValueOf[fwtypes.StringEnum[odbtypes.MonthName]] `tfsdk:"months"` - Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` - WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` + DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"days_of_week"` + HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` + LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` + Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"months"` + Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` + WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` +} +type dayWeekNameAutonomousVmClusterMaintenanceWindowDataSourceModel struct { + Name fwtypes.StringEnum[odbtypes.DayOfWeekName] `tfsdk:"name"` +} + +type monthNameAutonomousVmClusterMaintenanceWindowDataSourceModel struct { + Name fwtypes.StringEnum[odbtypes.MonthName] `tfsdk:"name"` } diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go index 8061ab284f3f..b45491f86e2c 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go @@ -6,21 +6,21 @@ import ( "context" "errors" "fmt" + "testing" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/odb" odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/errs" tfodb "github.com/hashicorp/terraform-provider-aws/internal/service/odb" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" - "testing" - - "github.com/hashicorp/terraform-plugin-testing/helper/resource" - "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/names" ) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go index 13f94ea8e8c9..02aa17d1a8af 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -6,26 +6,23 @@ import ( "context" "errors" "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/service/odb" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" - "github.com/hashicorp/terraform-provider-aws/internal/errs" - "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "strings" "testing" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/odb" + odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" - - "github.com/hashicorp/terraform-provider-aws/names" - - odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" - + "github.com/hashicorp/terraform-provider-aws/internal/errs" tfodb "github.com/hashicorp/terraform-provider-aws/internal/service/odb" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" ) type autonomousVMClusterResourceTest struct { diff --git a/internal/service/odb/service_package.go b/internal/service/odb/service_package.go deleted file mode 100644 index 32a962a8ab63..000000000000 --- a/internal/service/odb/service_package.go +++ /dev/null @@ -1,21 +0,0 @@ -//Copyright © 2025, Oracle and/or its affiliates. All rights reserved. - -package odb - -import ( - "context" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/service/odb" - "github.com/hashicorp/terraform-provider-aws/names" -) - -func (p *servicePackage) NewClient(ctx context.Context, config map[string]any) (*odb.Client, error) { - cfg := *(config["aws_sdkv2_config"].(*aws.Config)) - - return odb.NewFromConfig(cfg, - odb.WithEndpointResolverV2(newEndpointResolverV2()), - withBaseEndpoint(config[names.AttrEndpoint].(string)), - func(o *odb.Options) { - }, - ), nil -} diff --git a/internal/service/odb/service_package_gen.go b/internal/service/odb/service_package_gen.go index a44c1aa78cb0..e4ab1bb9e5bd 100644 --- a/internal/service/odb/service_package_gen.go +++ b/internal/service/odb/service_package_gen.go @@ -4,6 +4,7 @@ package odb import ( "context" + "unique" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/aws/retry" @@ -18,11 +19,31 @@ import ( type servicePackage struct{} func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*inttypes.ServicePackageFrameworkDataSource { - return []*inttypes.ServicePackageFrameworkDataSource{} + return []*inttypes.ServicePackageFrameworkDataSource{ + { + Factory: newDataSourceCloudAutonomousVmCluster, + TypeName: "aws_odb_cloud_autonomous_vm_cluster", + Name: "Cloud Autonomous Vm Cluster", + Tags: unique.Make(inttypes.ServicePackageResourceTags{ + IdentifierAttribute: names.AttrARN, + }), + Region: unique.Make(inttypes.ResourceRegionDefault()), + }, + } } func (p *servicePackage) FrameworkResources(ctx context.Context) []*inttypes.ServicePackageFrameworkResource { - return []*inttypes.ServicePackageFrameworkResource{} + return []*inttypes.ServicePackageFrameworkResource{ + { + Factory: newResourceCloudAutonomousVmCluster, + TypeName: "aws_odb_cloud_autonomous_vm_cluster", + Name: "Cloud Autonomous Vm Cluster", + Tags: unique.Make(inttypes.ServicePackageResourceTags{ + IdentifierAttribute: names.AttrARN, + }), + Region: unique.Make(inttypes.ResourceRegionDefault()), + }, + } } func (p *servicePackage) SDKDataSources(ctx context.Context) []*inttypes.ServicePackageSDKDataSource { diff --git a/names/data/names_data.hcl b/names/data/names_data.hcl index df75c89019b2..10685ba3c109 100644 --- a/names/data/names_data.hcl +++ b/names/data/names_data.hcl @@ -9521,32 +9521,3 @@ service "evs" { doc_prefix = ["evs_"] brand = "Amazon" } -service "odb" { - sdk { - id = "ODB" - arn_namespace = "odb" - } - names { - provider_name_upper = "ODB" - human_friendly = "Oracle Database@AWS" - } - endpoint_info { - endpoint_api_call = "ListGiVersions" - endpoint_region_overrides = { - "aws" = "us-east-1" - } - } - go_packages { - v1_package = "" - v2_package = "odb" - } - client{ - skip_client_generate = true - } - resource_prefix{ - correct = "aws_odb_" - } - provider_package_correct = "odb" - doc_prefix = ["odb_"] - brand = "AWS" -} \ No newline at end of file From 6c30443695ac39fa0eb48fecec65ea84de71970b Mon Sep 17 00:00:00 2001 From: Asim Date: Wed, 27 Aug 2025 10:30:03 +0100 Subject: [PATCH 07/42] fixed linting issues of avmc --- .../odb/cloud_autonomous_vm_cluster.go | 2 - ..._autonomous_vm_cluster_data_source_test.go | 48 ------------------- .../odb/cloud_autonomous_vm_cluster_test.go | 25 +++------- 3 files changed, 6 insertions(+), 69 deletions(-) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index e0eb88df779d..8c5cba3781cb 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -447,7 +447,6 @@ func (r *resourceCloudAutonomousVmCluster) Read(ctx context.Context, req resourc } func (r *resourceCloudAutonomousVmCluster) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan, state cloudAutonomousVmClusterResourceModel resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) resp.Diagnostics.Append(req.State.Get(ctx, &state)...) @@ -474,7 +473,6 @@ func (r *resourceCloudAutonomousVmCluster) Update(ctx context.Context, req resou } func (r *resourceCloudAutonomousVmCluster) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - conn := r.Meta().ODBClient(ctx) var state cloudAutonomousVmClusterResourceModel diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go index b45491f86e2c..0f611dbc0884 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go @@ -8,17 +8,14 @@ import ( "fmt" "testing" - "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/odb" odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" - "github.com/hashicorp/terraform-provider-aws/internal/errs" tfodb "github.com/hashicorp/terraform-provider-aws/internal/service/odb" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" @@ -63,50 +60,6 @@ func TestAccODBCloudAutonomousVmClusterDataSource_basic(t *testing.T) { }, }) } -func (autonomousVMClusterDSTest) checkCloudAutonomousVmClusterExists(ctx context.Context, name string, cloudAutonomousVMCluster *odbtypes.CloudAutonomousVmCluster) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[name] - if !ok { - return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, name, errors.New("not found")) - } - - if rs.Primary.ID == "" { - return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, name, errors.New("not set")) - } - - conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) - resp, err := autonomousVMClusterDSTestEntity.findAVMC(ctx, conn, rs.Primary.ID) - if err != nil { - return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, err) - } - - *cloudAutonomousVMCluster = *resp - - return nil - } -} - -func (autonomousVMClusterDSTest) findAVMC(ctx context.Context, conn *odb.Client, id string) (*odbtypes.CloudAutonomousVmCluster, error) { - input := odb.GetCloudAutonomousVmClusterInput{ - CloudAutonomousVmClusterId: aws.String(id), - } - out, err := conn.GetCloudAutonomousVmCluster(ctx, &input) - if err != nil { - if errs.IsA[*odbtypes.ResourceNotFoundException](err) { - return nil, &retry.NotFoundError{ - LastError: err, - LastRequest: &input, - } - } - return nil, err - } - - if out == nil || out.CloudAutonomousVmCluster == nil { - return nil, tfresource.NewEmptyResultError(&input) - } - - return out.CloudAutonomousVmCluster, nil -} func (autonomousVMClusterDSTest) testAccCheckCloudAutonomousVmClusterDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -147,7 +100,6 @@ func (autonomousVMClusterDSTest) testAccPreCheck(ctx context.Context, t *testing } func (autonomousVMClusterDSTest) avmcBasic() string { - exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go index 02aa17d1a8af..137a5507da63 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -276,8 +276,8 @@ func (autonomousVMClusterResourceTest) avmcBasic() string { odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) - exaInfraRes := autonomousVMClusterDSTestEntity.exaInfra(exaInfraDisplayName) - odbNetRes := autonomousVMClusterDSTestEntity.odbNet(odbNetworkDisplayName) + exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName) + odbNetRes := autonomousVMClusterResourceTestEntity.odbNet(odbNetworkDisplayName) res := fmt.Sprintf(` %s @@ -320,8 +320,8 @@ func (autonomousVMClusterResourceTest) avmcNoTagWithTag() (string, string) { odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) - exaInfraRes := autonomousVMClusterDSTestEntity.exaInfra(exaInfraDisplayName) - odbNetRes := autonomousVMClusterDSTestEntity.odbNet(odbNetworkDisplayName) + exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName) + odbNetRes := autonomousVMClusterResourceTestEntity.odbNet(odbNetworkDisplayName) noTag := fmt.Sprintf(` %s @@ -401,8 +401,8 @@ func (autonomousVMClusterResourceTest) avmcAllParamsConfig() string { odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) - exaInfraRes := autonomousVMClusterDSTestEntity.exaInfra(exaInfraDisplayName) - odbNetRes := autonomousVMClusterDSTestEntity.odbNet(odbNetworkDisplayName) + exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName) + odbNetRes := autonomousVMClusterResourceTestEntity.odbNet(odbNetworkDisplayName) res := fmt.Sprintf(` %s @@ -488,16 +488,3 @@ resource "aws_odb_cloud_exadata_infrastructure" "test" { return resource } -func (autonomousVMClusterResourceTest) odbNetwork(odbNetDisplayName string) string { - return fmt.Sprintf(` - resource "aws_odb_network" "test" { - display_name = %[1]q - availability_zone_id = "use1-az6" - client_subnet_cidr = "10.2.0.0/24" - backup_subnet_cidr = "10.2.1.0/24" - s3_access = "DISABLED" - zero_etl_access = "DISABLED" - } -`, odbNetDisplayName) - -} From 7dd02137750f0390b0dba9c9dc220017f365d5d9 Mon Sep 17 00:00:00 2001 From: Asim Date: Wed, 27 Aug 2025 10:59:55 +0100 Subject: [PATCH 08/42] fixed linting issues of avmc --- internal/service/odb/cloud_autonomous_vm_cluster.go | 12 ++++++------ .../odb/cloud_autonomous_vm_cluster_data_source.go | 8 ++++---- .../cloud_autonomous_vm_cluster_data_source_test.go | 2 +- .../service/odb/cloud_autonomous_vm_cluster_test.go | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index 8c5cba3781cb..f1ca186ed47d 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -123,7 +123,7 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou Computed: true, Description: "The percentage of total CPU cores currently in use in the Autonomous VM cluster.", }, - "created_at": schema.StringAttribute{ + names.AttrCreatedAt: schema.StringAttribute{ Computed: true, CustomType: timetypes.RFC3339Type{}, Description: "The date and time when the Autonomous VM cluster was created.", @@ -149,7 +149,7 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou }, Description: "The database servers in the Autonomous VM cluster. Changing this will force terraform to create new resource.", }, - "description": schema.StringAttribute{ + names.AttrDescription: schema.StringAttribute{ Optional: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), @@ -157,7 +157,7 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou }, Description: "The description of the Autonomous VM cluster.", }, - "display_name": schema.StringAttribute{ + names.AttrDisplayName: schema.StringAttribute{ Required: true, Validators: stringLengthBetween1And255Validator, PlanModifiers: []planmodifier.String{ @@ -165,7 +165,7 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou }, Description: "The display name of the Autonomous VM cluster. Changing this will force terraform to create new resource.", }, - "domain": schema.StringAttribute{ + names.AttrDomain: schema.StringAttribute{ Computed: true, Description: "The domain name of the Autonomous VM cluster.", }, @@ -283,12 +283,12 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou Computed: true, Description: "The shape of the Exadata infrastructure for the Autonomous VM cluster.", }, - "status": schema.StringAttribute{ + names.AttrStatus: schema.StringAttribute{ CustomType: status, Computed: true, Description: "The status of the Autonomous VM cluster. Possible values include CREATING, AVAILABLE , UPDATING , DELETING , DELETED , FAILED ", }, - "status_reason": schema.StringAttribute{ + names.AttrStatusReason: schema.StringAttribute{ Computed: true, Description: "Additional information about the current status of the Autonomous VM cluster.", }, diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go index 20d11239924c..ccd8542267e3 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go @@ -87,7 +87,7 @@ func (d *dataSourceCloudAutonomousVmCluster) Schema(ctx context.Context, req dat Computed: true, Description: "he percentage of total CPU cores currently in use in the Autonomous VM cluster.", }, - "created_at": schema.StringAttribute{ + names.AttrCreatedAt: schema.StringAttribute{ Computed: true, CustomType: timetypes.RFC3339Type{}, Description: "The date and time when the Autonomous VM cluster was created.", @@ -110,15 +110,15 @@ func (d *dataSourceCloudAutonomousVmCluster) Schema(ctx context.Context, req dat ElementType: types.StringType, Description: "The list of database servers associated with the Autonomous VM cluster.", }, - "description": schema.StringAttribute{ + names.AttrDescription: schema.StringAttribute{ Computed: true, Description: "The user-provided description of the Autonomous VM cluster.", }, - "display_name": schema.StringAttribute{ + names.AttrDisplayName: schema.StringAttribute{ Computed: true, Description: "The display name of the Autonomous VM cluster.", }, - "domain": schema.StringAttribute{ + names.AttrDomain: schema.StringAttribute{ Computed: true, Description: "The domain name of the Autonomous VM cluster.", }, diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go index 0f611dbc0884..b0163ba790b5 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go @@ -54,7 +54,7 @@ func TestAccODBCloudAutonomousVmClusterDataSource_basic(t *testing.T) { { Config: autonomousVMClusterDSTestEntity.avmcBasic(), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "display_name", *avmc1.DisplayName), + resource.TestCheckResourceAttr(dataSourceName, names.AttrDisplayName, *avmc1.DisplayName), ), }, }, diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go index 137a5507da63..d4c77eb12905 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -131,7 +131,7 @@ func TestAccODBCloudAutonomousVmClusterTagging(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &avmc1), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "0"), ), }, { @@ -143,7 +143,7 @@ func TestAccODBCloudAutonomousVmClusterTagging(t *testing.T) { Config: withTag, Check: resource.ComposeAggregateTestCheckFunc( autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &avmc2), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"), resource.TestCheckResourceAttr(resourceName, "tags.env", "dev"), resource.ComposeTestCheckFunc(func(state *terraform.State) error { if strings.Compare(*(avmc1.CloudAutonomousVmClusterId), *(avmc2.CloudAutonomousVmClusterId)) != 0 { From 6402ede08a6363464b45948d15a4e938de245497 Mon Sep 17 00:00:00 2001 From: Asim Date: Wed, 27 Aug 2025 19:09:23 +0100 Subject: [PATCH 09/42] fixed linting issues of avmc --- examples/odb/autonomous_vm_cluster.tf | 35 +-- .../odb/cloud_autonomous_vm_cluster.go | 14 +- ...cloud_autonomous_vm_cluster_data_source.go | 3 +- ..._autonomous_vm_cluster_data_source_test.go | 105 +++---- .../odb/cloud_autonomous_vm_cluster_test.go | 256 +++++++++--------- 5 files changed, 209 insertions(+), 204 deletions(-) diff --git a/examples/odb/autonomous_vm_cluster.tf b/examples/odb/autonomous_vm_cluster.tf index 540955f3a64a..fb7ce87eea03 100644 --- a/examples/odb/autonomous_vm_cluster.tf +++ b/examples/odb/autonomous_vm_cluster.tf @@ -1,9 +1,10 @@ -# Copyright © 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 # Autonomous VM Cluster with default maintenance window and minimum parameters resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_minimum_parameters" { cloud_exadata_infrastructure_id = "" # refer your exadata infra id - odb_network_id = "" # refer_your_odb_net_id + odb_network_id = "" # refer_your_odb_net_id display_name = "Ofake-avmc-my_avmc" autonomous_data_storage_size_in_tbs = 5 memory_per_oracle_compute_unit_in_gbs = 2 @@ -11,16 +12,16 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_minimum_parameters" { cpu_core_count_per_node = 40 license_model = "LICENSE_INCLUDED" # ids of db server. refer your exa infra. This is a manadatory fileld. Refer your cloud exadata infrastructure for db server id - db_servers = [""] - scan_listener_port_tls = 8561 - scan_listener_port_non_tls = 1024 + db_servers = [""] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 maintenance_window = { - preference = "NO_PREFERENCE" - days_of_week = [] - hours_of_day = [] - months = [] - weeks_of_month = [] - lead_time_in_weeks = 0 + preference = "NO_PREFERENCE" + days_of_week = [] + hours_of_day = [] + months = [] + weeks_of_month = [] + lead_time_in_weeks = 0 } } @@ -41,12 +42,12 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 maintenance_window = { - preference = "CUSTOM_PREFERENCE" - days_of_week = ["MONDAY", "TUESDAY"] - hours_of_day = [4, 16] - months = ["FEBRUARY", "MAY", "AUGUST", "NOVEMBER"] - weeks_of_month = [2, 4] - lead_time_in_weeks = 3 + preference = "CUSTOM_PREFERENCE" + days_of_week = ["MONDAY", "TUESDAY"] + hours_of_day = [4, 16] + months = ["FEBRUARY", "MAY", "AUGUST", "NOVEMBER"] + weeks_of_month = [2, 4] + lead_time_in_weeks = 3 } tags = { "env" = "dev" diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index f1ca186ed47d..7f7376a7dbd4 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -1,26 +1,26 @@ -// Copyright © 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package odb import ( "context" "errors" - "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" - "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/odb" odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/float64planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/int32planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" @@ -509,10 +509,6 @@ func (r *resourceCloudAutonomousVmCluster) Delete(ctx context.Context, req resou } } -func (r *resourceCloudAutonomousVmCluster) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root(names.AttrID), req, resp) -} - func waitCloudAutonomousVmClusterCreated(ctx context.Context, conn *odb.Client, id string, timeout time.Duration) (*odbtypes.CloudAutonomousVmCluster, error) { stateConf := &retry.StateChangeConf{ Pending: enum.Slice(odbtypes.ResourceStatusProvisioning), diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go index ccd8542267e3..1a1c19c3300e 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go @@ -1,4 +1,5 @@ -//Copyright © 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package odb diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go index b0163ba790b5..9b7d1fce8e01 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go @@ -1,4 +1,5 @@ -//Copyright © 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package odb_test @@ -86,11 +87,8 @@ func (autonomousVMClusterDSTest) testAccCheckCloudAutonomousVmClusterDestroy(ctx } func (autonomousVMClusterDSTest) testAccPreCheck(ctx context.Context, t *testing.T) { conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) - - input := &odb.ListCloudAutonomousVmClustersInput{} - - _, err := conn.ListCloudAutonomousVmClusters(ctx, input) - + input := odb.ListCloudAutonomousVmClustersInput{} + _, err := conn.ListCloudAutonomousVmClusters(ctx, &input) if acctest.PreCheckSkipError(err) { t.Skipf("skipping acceptance testing: %s", err) } @@ -103,9 +101,10 @@ func (autonomousVMClusterDSTest) avmcBasic() string { exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) - - exaInfraRes := autonomousVMClusterDSTestEntity.exaInfra(exaInfraDisplayName) - odbNetRes := autonomousVMClusterDSTestEntity.odbNet(odbNetworkDisplayName) + domain := acctest.RandomDomainName() + emailAddress := acctest.RandomEmailAddress(domain) + exaInfraRes := autonomousVMClusterDSTestEntity.exaInfra(exaInfraDisplayName, emailAddress) + odbNetRes := autonomousVMClusterDSTestEntity.oracleDBNetwork(odbNetworkDisplayName) res := fmt.Sprintf(` %s @@ -116,31 +115,29 @@ data "aws_odb_db_servers_list" "test" { } resource "aws_odb_cloud_autonomous_vm_cluster" "test" { - cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id - odb_network_id =aws_odb_network.test.id - display_name = %[3]q - autonomous_data_storage_size_in_tbs = 5 - memory_per_oracle_compute_unit_in_gbs = 2 - total_container_databases = 1 - cpu_core_count_per_node = 40 - license_model = "LICENSE_INCLUDED" - db_servers = [ for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] - scan_listener_port_tls = 8561 - scan_listener_port_non_tls = 1024 - maintenance_window = { - preference = "NO_PREFERENCE" - days_of_week = [] - hours_of_day = [] - months = [] - weeks_of_month =[] - lead_time_in_weeks = 0 - } + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id = aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + custom_action_timeout_in_mins = 16 + is_custom_action_timeout_enabled = true + patching_mode = "ROLLING" + preference = "NO_PREFERENCE" + } } data "aws_odb_cloud_autonomous_vm_cluster" "test" { - id = aws_odb_cloud_autonomous_vm_cluster.test.id + id = aws_odb_cloud_autonomous_vm_cluster.test.id } `, exaInfraRes, odbNetRes, avmcDisplayName) @@ -148,47 +145,53 @@ data "aws_odb_cloud_autonomous_vm_cluster" "test" { return res } -func (autonomousVMClusterDSTest) odbNet(odbNetName string) string { +func (autonomousVMClusterDSTest) oracleDBNetwork(odbNetName string) string { networkRes := fmt.Sprintf(` + + resource "aws_odb_network" "test" { - display_name = %[1]q + display_name = %[1]q availability_zone_id = "use1-az6" client_subnet_cidr = "10.2.0.0/24" backup_subnet_cidr = "10.2.1.0/24" - s3_access = "DISABLED" - zero_etl_access = "DISABLED" + s3_access = "DISABLED" + zero_etl_access = "DISABLED" } + `, odbNetName) return networkRes } -func (autonomousVMClusterDSTest) exaInfra(exaInfraName string) string { +func (autonomousVMClusterDSTest) exaInfra(exaInfraName, emailAddress string) string { exaInfraRes := fmt.Sprintf(` + + resource "aws_odb_cloud_exadata_infrastructure" "test" { - display_name = %[1]q - shape = "Exadata.X9M" - storage_count = 3 - compute_count = 2 - availability_zone_id = "use1-az6" - customer_contacts_to_send_to_oci = ["abc@example.com"] -maintenance_window = { - custom_action_timeout_in_mins = 16 - days_of_week = [] - hours_of_day = [] - is_custom_action_timeout_enabled = true - lead_time_in_weeks = 0 - months = [] - patching_mode = "ROLLING" - preference = "NO_PREFERENCE" - weeks_of_month =[] + display_name = %[1]q + shape = "Exadata.X9M" + storage_count = 3 + compute_count = 2 + availability_zone_id = "use1-az6" + customer_contacts_to_send_to_oci = ["%[2]s"] + maintenance_window = { + custom_action_timeout_in_mins = 16 + days_of_week = [] + hours_of_day = [] + is_custom_action_timeout_enabled = true + lead_time_in_weeks = 0 + months = [] + patching_mode = "ROLLING" + preference = "NO_PREFERENCE" + weeks_of_month = [] } } -`, exaInfraName) + +`, exaInfraName, emailAddress) return exaInfraRes } diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go index d4c77eb12905..72a01b6eee10 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -1,4 +1,5 @@ -//Copyright © 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package odb_test @@ -37,7 +38,7 @@ var autonomousVMClusterResourceTestEntity = autonomousVMClusterResourceTest{ autonomousVmClusterDisplayNamePrefix: "Ofake-avmc", } -func TestAccODBCloudAutonomousVmClusterCreationBasic(t *testing.T) { +func TestAccODBCloudAutonomousVmCluster_basic(t *testing.T) { ctx := acctest.Context(t) if testing.Short() { t.Skip("skipping long-running test in short mode") @@ -71,7 +72,7 @@ func TestAccODBCloudAutonomousVmClusterCreationBasic(t *testing.T) { }) } -func TestAccODBCloudAutonomousVmClusterCreationWithAllParams(t *testing.T) { +func TestAccODBCloudAutonomousVmCluster_withAllParams(t *testing.T) { ctx := acctest.Context(t) if testing.Short() { t.Skip("skipping long-running test in short mode") @@ -106,8 +107,7 @@ func TestAccODBCloudAutonomousVmClusterCreationWithAllParams(t *testing.T) { }) } -func TestAccODBCloudAutonomousVmClusterTagging(t *testing.T) { - fmt.Println("Update tags test") +func TestAccODBCloudAutonomousVmCluster_tagging(t *testing.T) { ctx := acctest.Context(t) if testing.Short() { t.Skip("skipping long-running test in short mode") @@ -188,11 +188,8 @@ func TestAccODBCloudAutonomousVmCluster_disappears(t *testing.T) { func (autonomousVMClusterResourceTest) testAccPreCheck(ctx context.Context, t *testing.T) { conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) - - input := &odb.ListCloudAutonomousVmClustersInput{} - - _, err := conn.ListCloudAutonomousVmClusters(ctx, input) - + input := odb.ListCloudAutonomousVmClustersInput{} + _, err := conn.ListCloudAutonomousVmClusters(ctx, &input) if acctest.PreCheckSkipError(err) { t.Skipf("skipping acceptance testing: %s", err) } @@ -236,7 +233,6 @@ func (autonomousVMClusterResourceTest) checkCloudAutonomousVmClusterExists(ctx c } conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) - fmt.Println("") resp, err := autonomousVMClusterResourceTestEntity.findAVMC(ctx, conn, rs.Primary.ID) if err != nil { return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, err) @@ -271,13 +267,13 @@ func (autonomousVMClusterResourceTest) findAVMC(ctx context.Context, conn *odb.C } func (autonomousVMClusterResourceTest) avmcBasic() string { - exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) - - exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName) - odbNetRes := autonomousVMClusterResourceTestEntity.odbNet(odbNetworkDisplayName) + domain := acctest.RandomDomainName() + emailAddress := acctest.RandomEmailAddress(domain) + exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName, emailAddress) + odbNetRes := autonomousVMClusterResourceTestEntity.oracleDBNetwork(odbNetworkDisplayName) res := fmt.Sprintf(` %s @@ -288,28 +284,29 @@ data "aws_odb_db_servers_list" "test" { } resource "aws_odb_cloud_autonomous_vm_cluster" "test" { - cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id - odb_network_id =aws_odb_network.test.id - display_name = %[3]q - autonomous_data_storage_size_in_tbs = 5 - memory_per_oracle_compute_unit_in_gbs = 2 - total_container_databases = 1 - cpu_core_count_per_node = 40 - license_model = "LICENSE_INCLUDED" - db_servers = [ for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] - scan_listener_port_tls = 8561 - scan_listener_port_non_tls = 1024 - maintenance_window = { - preference = "NO_PREFERENCE" - days_of_week = [] - hours_of_day = [] - months = [] - weeks_of_month =[] - lead_time_in_weeks = 0 - } + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id = aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "NO_PREFERENCE" + days_of_week = [] + hours_of_day = [] + months = [] + weeks_of_month = [] + lead_time_in_weeks = 0 + } } + `, exaInfraRes, odbNetRes, avmcDisplayName) return res @@ -319,9 +316,10 @@ func (autonomousVMClusterResourceTest) avmcNoTagWithTag() (string, string) { exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) - - exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName) - odbNetRes := autonomousVMClusterResourceTestEntity.odbNet(odbNetworkDisplayName) + domain := acctest.RandomDomainName() + emailAddress := acctest.RandomEmailAddress(domain) + exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName, emailAddress) + odbNetRes := autonomousVMClusterResourceTestEntity.oracleDBNetwork(odbNetworkDisplayName) noTag := fmt.Sprintf(` %s @@ -332,28 +330,29 @@ data "aws_odb_db_servers_list" "test" { } resource "aws_odb_cloud_autonomous_vm_cluster" "test" { - cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id - odb_network_id =aws_odb_network.test.id - display_name = %[3]q - autonomous_data_storage_size_in_tbs = 5 - memory_per_oracle_compute_unit_in_gbs = 2 - total_container_databases = 1 - cpu_core_count_per_node = 40 - license_model = "LICENSE_INCLUDED" - db_servers = [ for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] - scan_listener_port_tls = 8561 - scan_listener_port_non_tls = 1024 - maintenance_window = { - preference = "NO_PREFERENCE" - days_of_week = [] - hours_of_day = [] - months = [] - weeks_of_month =[] - lead_time_in_weeks = 0 - } - + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id = aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "NO_PREFERENCE" + days_of_week = [] + hours_of_day = [] + months = [] + weeks_of_month = [] + lead_time_in_weeks = 0 + } + } + `, exaInfraRes, odbNetRes, avmcDisplayName) withTag := fmt.Sprintf(` %s @@ -365,44 +364,45 @@ data "aws_odb_db_servers_list" "test" { } resource "aws_odb_cloud_autonomous_vm_cluster" "test" { - cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id - odb_network_id =aws_odb_network.test.id - display_name = %[3]q - autonomous_data_storage_size_in_tbs = 5 - memory_per_oracle_compute_unit_in_gbs = 2 - total_container_databases = 1 - cpu_core_count_per_node = 40 - license_model = "LICENSE_INCLUDED" - db_servers = [ for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] - scan_listener_port_tls = 8561 - scan_listener_port_non_tls = 1024 - maintenance_window = { - preference = "NO_PREFERENCE" - days_of_week = [] - hours_of_day = [] - months = [] - weeks_of_month =[] - lead_time_in_weeks = 0 - } + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id = aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "NO_PREFERENCE" + days_of_week = [] + hours_of_day = [] + months = [] + weeks_of_month = [] + lead_time_in_weeks = 0 + } tags = { - "env"= "dev" + "env" = "dev" } } + `, exaInfraRes, odbNetRes, avmcDisplayName) return noTag, withTag } func (autonomousVMClusterResourceTest) avmcAllParamsConfig() string { - exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) - - exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName) - odbNetRes := autonomousVMClusterResourceTestEntity.odbNet(odbNetworkDisplayName) + domain := acctest.RandomDomainName() + emailAddress := acctest.RandomEmailAddress(domain) + exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName, emailAddress) + odbNetRes := autonomousVMClusterResourceTestEntity.oracleDBNetwork(odbNetworkDisplayName) res := fmt.Sprintf(` %s @@ -413,78 +413,82 @@ data "aws_odb_db_servers_list" "test" { } resource "aws_odb_cloud_autonomous_vm_cluster" "test" { - description = "my first avmc" - time_zone = "UTC" - cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id - odb_network_id =aws_odb_network.test.id - display_name = %[3]q - autonomous_data_storage_size_in_tbs = 5 - memory_per_oracle_compute_unit_in_gbs = 2 - total_container_databases = 1 - cpu_core_count_per_node = 40 - license_model = "LICENSE_INCLUDED" - db_servers = [ for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] - scan_listener_port_tls = 8561 - scan_listener_port_non_tls = 1024 - maintenance_window = { - preference = "CUSTOM_PREFERENCE" - days_of_week = ["MONDAY", "TUESDAY"] - hours_of_day = [4,16] - months = ["FEBRUARY","MAY","AUGUST","NOVEMBER"] - weeks_of_month =[2,4] - lead_time_in_weeks = 3 - } + description = "my first avmc" + time_zone = "UTC" + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id = aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window = { + preference = "CUSTOM_PREFERENCE" + days_of_week = ["MONDAY", "TUESDAY"] + hours_of_day = [4, 16] + months = ["FEBRUARY", "MAY", "AUGUST", "NOVEMBER"] + weeks_of_month = [2, 4] + lead_time_in_weeks = 3 + } tags = { - "env"= "dev" + "env" = "dev" } } + `, exaInfraRes, odbNetRes, avmcDisplayName) return res } -func (autonomousVMClusterResourceTest) odbNet(odbNetName string) string { +func (autonomousVMClusterResourceTest) oracleDBNetwork(odbNetName string) string { networkRes := fmt.Sprintf(` + + resource "aws_odb_network" "test" { - display_name = %[1]q + display_name = %[1]q availability_zone_id = "use1-az6" client_subnet_cidr = "10.2.0.0/24" backup_subnet_cidr = "10.2.1.0/24" - s3_access = "DISABLED" - zero_etl_access = "DISABLED" + s3_access = "DISABLED" + zero_etl_access = "DISABLED" } + `, odbNetName) return networkRes } -func (autonomousVMClusterResourceTest) exaInfra(exaDisplayName string) string { +func (autonomousVMClusterResourceTest) exaInfra(exaDisplayName, emailAddress string) string { resource := fmt.Sprintf(` resource "aws_odb_cloud_exadata_infrastructure" "test" { - display_name = "%[1]s" - shape = "Exadata.X9M" - storage_count = 3 - compute_count = 2 - availability_zone_id = "use1-az6" - customer_contacts_to_send_to_oci = ["abc@example.com"] - - maintenance_window = { - custom_action_timeout_in_mins = 16 - days_of_week = [] - hours_of_day = [] - is_custom_action_timeout_enabled = true - lead_time_in_weeks = 0 - months = [] - patching_mode = "ROLLING" - preference = "NO_PREFERENCE" - weeks_of_month =[] + display_name = "%[1]s" + shape = "Exadata.X9M" + storage_count = 3 + compute_count = 2 + availability_zone_id = "use1-az6" + customer_contacts_to_send_to_oci = ["%[2]s"] + + maintenance_window = { + custom_action_timeout_in_mins = 16 + days_of_week = [] + hours_of_day = [] + is_custom_action_timeout_enabled = true + lead_time_in_weeks = 0 + months = [] + patching_mode = "ROLLING" + preference = "NO_PREFERENCE" + weeks_of_month = [] } } -`, exaDisplayName) +`, exaDisplayName, emailAddress) return resource } From 89ad1142d0aae68ea4adaec515dde73eabc3efbe Mon Sep 17 00:00:00 2001 From: Asim Date: Fri, 29 Aug 2025 16:07:23 +0100 Subject: [PATCH 10/42] fixed linting issues and refactoring AVMC as per exa-infra PR feedback --- .../odb/cloud_autonomous_vm_cluster.go | 64 +++++++++++++------ ...cloud_autonomous_vm_cluster_data_source.go | 18 +++--- ..._autonomous_vm_cluster_data_source_test.go | 3 +- .../odb/cloud_autonomous_vm_cluster_test.go | 44 ++++--------- 4 files changed, 68 insertions(+), 61 deletions(-) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index 7f7376a7dbd4..8b61ac62e399 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -1,5 +1,4 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. package odb @@ -60,6 +59,7 @@ var ResourceCloudAutonomousVMCluster = newResourceCloudAutonomousVmCluster type resourceCloudAutonomousVmCluster struct { framework.ResourceWithModel[cloudAutonomousVmClusterResourceModel] framework.WithTimeouts + framework.WithImportByID } func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { @@ -339,30 +339,55 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou NestedObject: schema.NestedBlockObject{ Attributes: map[string]schema.Attribute{ - "days_of_week": schema.SetAttribute{ - ElementType: fwtypes.NewObjectTypeOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel](ctx), + "custom_action_timeout_in_mins": schema.Int32Attribute{ Optional: true, Computed: true, - Description: "The day of week of the Autonomous VM cluster.", + Description: "The custom action timeout in minutes for the maintenance window.", }, - "months": schema.SetAttribute{ - ElementType: fwtypes.NewObjectTypeOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel](ctx), + "days_of_week": schema.SetAttribute{ + ElementType: fwtypes.NewObjectTypeOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel](ctx), Optional: true, Computed: true, - Description: "The month of the Autonomous VM cluster.", + Description: "The days of the week when maintenance can be performed.", }, "hours_of_day": schema.SetAttribute{ ElementType: types.Int32Type, Optional: true, Computed: true, + Description: "The hours of the day when maintenance can be performed.", + }, + "is_custom_action_timeout_enabled": schema.BoolAttribute{ + Optional: true, + Computed: true, + Description: "Indicates whether custom action timeout is enabled for the maintenance window.", }, "lead_time_in_weeks": schema.Int32Attribute{ - Optional: true, - Computed: true, + Optional: true, + Computed: true, + Description: "The lead time in weeks before the maintenance window.", + }, + "months": schema.SetAttribute{ + ElementType: fwtypes.NewObjectTypeOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel](ctx), + Optional: true, + Computed: true, + Description: "The months when maintenance can be performed.", + }, + "patching_mode": schema.StringAttribute{ + Optional: true, + Computed: true, + CustomType: fwtypes.StringEnumType[odbtypes.PatchingModeType](), + Description: "The patching mode for the maintenance window.", }, "preference": schema.StringAttribute{ - Required: true, - CustomType: fwtypes.StringEnumType[odbtypes.PreferenceType](), + Required: true, + CustomType: fwtypes.StringEnumType[odbtypes.PreferenceType](), + Description: "The preference for the maintenance window scheduling.", + }, + "weeks_of_month": schema.SetAttribute{ + ElementType: types.Int32Type, + Optional: true, + Computed: true, + Description: "Indicates whether to skip release updates during maintenance.", }, }, }, @@ -651,12 +676,15 @@ type cloudAutonomousVmClusterResourceModel struct { } type cloudAutonomousVmClusterMaintenanceWindowResourceModel struct { - DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"days_of_week"` - HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` - LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` - Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"months"` - Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` - WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` + CustomActionTimeoutInMins types.Int32 `tfsdk:"custom_action_timeout_in_mins"` + DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"days_of_week"` + HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` + IsCustomActionTimeoutEnabled types.Bool `tfsdk:"is_custom_action_timeout_enabled"` + LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` + Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"months"` + PatchingMode fwtypes.StringEnum[odbtypes.PatchingModeType] `tfsdk:"patching_mode"` + Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` + WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` } type dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel struct { diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go index 1a1c19c3300e..ac7f8334702d 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go @@ -1,5 +1,4 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. package odb @@ -330,12 +329,15 @@ type cloudAutonomousVmClusterDataSourceModel struct { Tags tftags.Map `tfsdk:"tags"` } type cloudAutonomousVmClusterMaintenanceWindowDataSourceModel struct { - DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"days_of_week"` - HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` - LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` - Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"months"` - Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` - WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` + CustomActionTimeoutInMins types.Int32 `tfsdk:"custom_action_timeout_in_mins"` + DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"days_of_week"` + HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` + IsCustomActionTimeoutEnabled types.Bool `tfsdk:"is_custom_action_timeout_enabled"` + LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` + Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"months"` + PatchingMode fwtypes.StringEnum[odbtypes.PatchingModeType] `tfsdk:"patching_mode"` + Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` + WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` } type dayWeekNameAutonomousVmClusterMaintenanceWindowDataSourceModel struct { Name fwtypes.StringEnum[odbtypes.DayOfWeekName] `tfsdk:"name"` diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go index 9b7d1fce8e01..f6a7e42406bd 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go @@ -1,5 +1,4 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. package odb_test diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go index 72a01b6eee10..1f75b1d8dc6b 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -1,5 +1,4 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. package odb_test @@ -34,7 +33,7 @@ type autonomousVMClusterResourceTest struct { var autonomousVMClusterResourceTestEntity = autonomousVMClusterResourceTest{ exaInfraDisplayNamePrefix: "Ofake-exa", - odbNetDisplayNamePrefix: "odb-net", + odbNetDisplayNamePrefix: "oracleDB-net", autonomousVmClusterDisplayNamePrefix: "Ofake-avmc", } @@ -295,13 +294,8 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 - maintenance_window = { + maintenance_window { preference = "NO_PREFERENCE" - days_of_week = [] - hours_of_day = [] - months = [] - weeks_of_month = [] - lead_time_in_weeks = 0 } } @@ -341,13 +335,8 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 - maintenance_window = { + maintenance_window { preference = "NO_PREFERENCE" - days_of_week = [] - hours_of_day = [] - months = [] - weeks_of_month = [] - lead_time_in_weeks = 0 } } @@ -375,13 +364,8 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 - maintenance_window = { + maintenance_window { preference = "NO_PREFERENCE" - days_of_week = [] - hours_of_day = [] - months = [] - weeks_of_month = [] - lead_time_in_weeks = 0 } tags = { "env" = "dev" @@ -426,11 +410,11 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 - maintenance_window = { + maintenance_window { preference = "CUSTOM_PREFERENCE" - days_of_week = ["MONDAY", "TUESDAY"] + days_of_week = [{ name = "MONDAY" }, { name = "TUESDAY" }] hours_of_day = [4, 16] - months = ["FEBRUARY", "MAY", "AUGUST", "NOVEMBER"] + months = [{ name = "FEBRUARY" }, { name = "MAY" }, { name = "AUGUST" }, { name = "NOVEMBER" }] weeks_of_month = [2, 4] lead_time_in_weeks = 3 } @@ -469,23 +453,17 @@ resource "aws_odb_network" "test" { func (autonomousVMClusterResourceTest) exaInfra(exaDisplayName, emailAddress string) string { resource := fmt.Sprintf(` resource "aws_odb_cloud_exadata_infrastructure" "test" { - display_name = "%[1]s" + display_name = %[1]q shape = "Exadata.X9M" storage_count = 3 compute_count = 2 availability_zone_id = "use1-az6" - customer_contacts_to_send_to_oci = ["%[2]s"] - - maintenance_window = { + customer_contacts_to_send_to_oci = [{ email = "%[2]s" }] + maintenance_window { custom_action_timeout_in_mins = 16 - days_of_week = [] - hours_of_day = [] is_custom_action_timeout_enabled = true - lead_time_in_weeks = 0 - months = [] patching_mode = "ROLLING" preference = "NO_PREFERENCE" - weeks_of_month = [] } } `, exaDisplayName, emailAddress) From ebf42103aa1d36337372ca01757643b5b7be8db6 Mon Sep 17 00:00:00 2001 From: Asim Date: Fri, 29 Aug 2025 18:13:50 +0100 Subject: [PATCH 11/42] added documentation and fixed linter --- examples/odb/autonomous_vm_cluster.tf | 22 +-- .../odb/cloud_autonomous_vm_cluster.go | 58 +++---- ...cloud_autonomous_vm_cluster_data_source.go | 19 +-- ..._autonomous_vm_cluster_data_source_test.go | 15 +- .../odb/cloud_autonomous_vm_cluster_test.go | 20 ++- ..._cloud_autonomous_vm_cluster.html.markdown | 84 ++++++++++ ..._cloud_autonomous_vm_cluster.html.markdown | 151 ++++++++++++++++++ 7 files changed, 296 insertions(+), 73 deletions(-) create mode 100644 website/docs/d/odb_cloud_autonomous_vm_cluster.html.markdown create mode 100644 website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown diff --git a/examples/odb/autonomous_vm_cluster.tf b/examples/odb/autonomous_vm_cluster.tf index fb7ce87eea03..66ce3eeab83f 100644 --- a/examples/odb/autonomous_vm_cluster.tf +++ b/examples/odb/autonomous_vm_cluster.tf @@ -1,5 +1,4 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. # Autonomous VM Cluster with default maintenance window and minimum parameters resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_minimum_parameters" { @@ -15,13 +14,8 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_minimum_parameters" { db_servers = [""] scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 - maintenance_window = { - preference = "NO_PREFERENCE" - days_of_week = [] - hours_of_day = [] - months = [] - weeks_of_month = [] - lead_time_in_weeks = 0 + maintenance_window { + preference = "NO_PREFERENCE" } } @@ -41,13 +35,13 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { db_servers = ["", ""] scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 - maintenance_window = { - preference = "CUSTOM_PREFERENCE" - days_of_week = ["MONDAY", "TUESDAY"] + maintenance_window { + days_of_week = [{ name = "MONDAY" }, { name = "TUESDAY" }] hours_of_day = [4, 16] - months = ["FEBRUARY", "MAY", "AUGUST", "NOVEMBER"] - weeks_of_month = [2, 4] lead_time_in_weeks = 3 + months = [{ name = "FEBRUARY" }, { name = "MAY" }, { name = "AUGUST" }, { name = "NOVEMBER" }] + preference = "CUSTOM_PREFERENCE" + weeks_of_month = [2, 4] } tags = { "env" = "dev" diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index 8b61ac62e399..7a0d96344874 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -339,55 +339,52 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou NestedObject: schema.NestedBlockObject{ Attributes: map[string]schema.Attribute{ - "custom_action_timeout_in_mins": schema.Int32Attribute{ - Optional: true, - Computed: true, - Description: "The custom action timeout in minutes for the maintenance window.", - }, "days_of_week": schema.SetAttribute{ ElementType: fwtypes.NewObjectTypeOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel](ctx), Optional: true, - Computed: true, Description: "The days of the week when maintenance can be performed.", + PlanModifiers: []planmodifier.Set{ + setplanmodifier.RequiresReplace(), + }, }, "hours_of_day": schema.SetAttribute{ - ElementType: types.Int32Type, + ElementType: types.Int64Type, Optional: true, - Computed: true, Description: "The hours of the day when maintenance can be performed.", - }, - "is_custom_action_timeout_enabled": schema.BoolAttribute{ - Optional: true, - Computed: true, - Description: "Indicates whether custom action timeout is enabled for the maintenance window.", + PlanModifiers: []planmodifier.Set{ + setplanmodifier.RequiresReplace(), + }, }, "lead_time_in_weeks": schema.Int32Attribute{ Optional: true, - Computed: true, Description: "The lead time in weeks before the maintenance window.", + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, }, "months": schema.SetAttribute{ ElementType: fwtypes.NewObjectTypeOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel](ctx), Optional: true, - Computed: true, Description: "The months when maintenance can be performed.", - }, - "patching_mode": schema.StringAttribute{ - Optional: true, - Computed: true, - CustomType: fwtypes.StringEnumType[odbtypes.PatchingModeType](), - Description: "The patching mode for the maintenance window.", + PlanModifiers: []planmodifier.Set{ + setplanmodifier.RequiresReplace(), + }, }, "preference": schema.StringAttribute{ Required: true, CustomType: fwtypes.StringEnumType[odbtypes.PreferenceType](), Description: "The preference for the maintenance window scheduling.", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, }, "weeks_of_month": schema.SetAttribute{ - ElementType: types.Int32Type, + ElementType: types.Int64Type, Optional: true, - Computed: true, Description: "Indicates whether to skip release updates during maintenance.", + PlanModifiers: []planmodifier.Set{ + setplanmodifier.RequiresReplace(), + }, }, }, }, @@ -676,15 +673,12 @@ type cloudAutonomousVmClusterResourceModel struct { } type cloudAutonomousVmClusterMaintenanceWindowResourceModel struct { - CustomActionTimeoutInMins types.Int32 `tfsdk:"custom_action_timeout_in_mins"` - DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"days_of_week"` - HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` - IsCustomActionTimeoutEnabled types.Bool `tfsdk:"is_custom_action_timeout_enabled"` - LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` - Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"months"` - PatchingMode fwtypes.StringEnum[odbtypes.PatchingModeType] `tfsdk:"patching_mode"` - Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` - WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` + DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"days_of_week"` + HoursOfDay fwtypes.SetValueOf[types.Int64] `tfsdk:"hours_of_day"` + LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` + Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"months"` + Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` + WeeksOfMonth fwtypes.SetValueOf[types.Int64] `tfsdk:"weeks_of_month"` } type dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel struct { diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go index ac7f8334702d..16f2c917113e 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go @@ -235,7 +235,8 @@ func (d *dataSourceCloudAutonomousVmCluster) Schema(ctx context.Context, req dat Description: "The time zone of the Autonomous VM cluster.", }, "total_container_databases": schema.Int32Attribute{ - Computed: true, + Computed: true, + Description: "The total number of Autonomous Container Databases that can be created with the allocated local storage.", }, names.AttrTags: tftags.TagsAttributeComputedOnly(), "maintenance_window": schema.ListAttribute{ @@ -249,7 +250,6 @@ func (d *dataSourceCloudAutonomousVmCluster) Schema(ctx context.Context, req dat func (d *dataSourceCloudAutonomousVmCluster) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { conn := d.Meta().ODBClient(ctx) - var data cloudAutonomousVmClusterDataSourceModel resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) if resp.Diagnostics.HasError() { @@ -329,15 +329,12 @@ type cloudAutonomousVmClusterDataSourceModel struct { Tags tftags.Map `tfsdk:"tags"` } type cloudAutonomousVmClusterMaintenanceWindowDataSourceModel struct { - CustomActionTimeoutInMins types.Int32 `tfsdk:"custom_action_timeout_in_mins"` - DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"days_of_week"` - HoursOfDay fwtypes.SetValueOf[types.Int32] `tfsdk:"hours_of_day"` - IsCustomActionTimeoutEnabled types.Bool `tfsdk:"is_custom_action_timeout_enabled"` - LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` - Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"months"` - PatchingMode fwtypes.StringEnum[odbtypes.PatchingModeType] `tfsdk:"patching_mode"` - Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` - WeeksOfMonth fwtypes.SetValueOf[types.Int32] `tfsdk:"weeks_of_month"` + DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"days_of_week"` + HoursOfDay fwtypes.SetValueOf[types.Int64] `tfsdk:"hours_of_day"` + LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` + Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"months"` + Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` + WeeksOfMonth fwtypes.SetValueOf[types.Int64] `tfsdk:"weeks_of_month"` } type dayWeekNameAutonomousVmClusterMaintenanceWindowDataSourceModel struct { Name fwtypes.StringEnum[odbtypes.DayOfWeekName] `tfsdk:"name"` diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go index f6a7e42406bd..d01c24a71527 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go @@ -126,10 +126,10 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 maintenance_window { - custom_action_timeout_in_mins = 16 - is_custom_action_timeout_enabled = true - patching_mode = "ROLLING" - preference = "NO_PREFERENCE" + preference = "NO_PREFERENCE" + } + tags = { + "env" = "dev" } } @@ -177,16 +177,11 @@ resource "aws_odb_cloud_exadata_infrastructure" "test" { compute_count = 2 availability_zone_id = "use1-az6" customer_contacts_to_send_to_oci = ["%[2]s"] - maintenance_window = { + maintenance_window { custom_action_timeout_in_mins = 16 - days_of_week = [] - hours_of_day = [] is_custom_action_timeout_enabled = true - lead_time_in_weeks = 0 - months = [] patching_mode = "ROLLING" preference = "NO_PREFERENCE" - weeks_of_month = [] } } diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go index 1f75b1d8dc6b..c5357ddbe271 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -294,13 +294,15 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 - maintenance_window { - preference = "NO_PREFERENCE" + maintenance_window { + preference = "NO_PREFERENCE" } } + + `, exaInfraRes, odbNetRes, avmcDisplayName) return res @@ -336,12 +338,14 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 maintenance_window { - preference = "NO_PREFERENCE" + preference = "NO_PREFERENCE" } } + + `, exaInfraRes, odbNetRes, avmcDisplayName) withTag := fmt.Sprintf(` %s @@ -365,7 +369,7 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 maintenance_window { - preference = "NO_PREFERENCE" + preference = "NO_PREFERENCE" } tags = { "env" = "dev" @@ -374,6 +378,8 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { } + + `, exaInfraRes, odbNetRes, avmcDisplayName) return noTag, withTag @@ -411,12 +417,12 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { scan_listener_port_tls = 8561 scan_listener_port_non_tls = 1024 maintenance_window { - preference = "CUSTOM_PREFERENCE" days_of_week = [{ name = "MONDAY" }, { name = "TUESDAY" }] hours_of_day = [4, 16] + lead_time_in_weeks = 3 months = [{ name = "FEBRUARY" }, { name = "MAY" }, { name = "AUGUST" }, { name = "NOVEMBER" }] + preference = "CUSTOM_PREFERENCE" weeks_of_month = [2, 4] - lead_time_in_weeks = 3 } tags = { "env" = "dev" @@ -425,6 +431,8 @@ resource "aws_odb_cloud_autonomous_vm_cluster" "test" { } + + `, exaInfraRes, odbNetRes, avmcDisplayName) return res diff --git a/website/docs/d/odb_cloud_autonomous_vm_cluster.html.markdown b/website/docs/d/odb_cloud_autonomous_vm_cluster.html.markdown new file mode 100644 index 000000000000..93994d0b85e6 --- /dev/null +++ b/website/docs/d/odb_cloud_autonomous_vm_cluster.html.markdown @@ -0,0 +1,84 @@ +--- +subcategory: "Oracle Database@AWS" +layout: "AWS: aws_odb_cloud_autonomous_vm_cluster" +page_title: "AWS: aws_odb_cloud_autonomous_vm_cluster" +description: |- + Terraform data source for managing cloud autonomous vm cluster resource in AWS for Oracle Database@AWS. +--- + +# Data Source: aws_odb_cloud_autonomous_vm_cluster + +Terraform data source for managing cloud autonomous vm cluster resource in AWS for Oracle Database@AWS. + +You can find out more about Oracle Database@AWS from [User Guide](https://docs.aws.amazon.com/odb/latest/UserGuide/what-is-odb.html). + +## Example Usage + +### Basic Usage + +```terraform +data "aws_odb_cloud_autonomous_vm_cluster" "example" { + id = "example" +} +``` + +## Argument Reference + +The following arguments are optional: + +* `id` - (Required) The unique identifier of the cloud autonomous vm cluster. +* `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference). + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `arn` - The Amazon Resource Name (ARN) for the Exadata infrastructure. +* `cloud_exadata_infrastructure_id` - Cloud exadata infrastructure id associated with this cloud autonomous VM cluster. +* `autonomous_data_storage_percentage` - The percentage of data storage currently in use for Autonomous Databases in the Autonomous VM cluster. +* `autonomous_data_storage_size_in_tbs` - The data storage size allocated for Autonomous Databases in the Autonomous VM cluster, in TB. +* `available_autonomous_data_storage_size_in_tbs` - The available data storage space for Autonomous Databases in the Autonomous VM cluster, in TB. +* `available_container_databases` - The number of Autonomous CDBs that you can create with the currently available storage. +* `available_cpus` - The number of CPU cores available for allocation to Autonomous Databases. +* `compute_model` - The compute model of the Autonomous VM cluster: ECPU or OCPU. +* `cpu_core_count` - The total number of CPU cores in the Autonomous VM cluster. +* `cpu_core_count_per_node` - The number of CPU cores enabled per node in the Autonomous VM cluster. +* `cpu_percentage` - he percentage of total CPU cores currently in use in the Autonomous VM cluster. +* `created_at` - The date and time when the Autonomous VM cluster was created. +* `data_storage_size_in_gbs` - The total data storage allocated to the Autonomous VM cluster, in GB. +* `data_storage_size_in_tbs` - The total data storage allocated to the Autonomous VM cluster, in TB. +* `odb_node_storage_size_in_gbs` - The local node storage allocated to the Autonomous VM cluster, in gigabytes (GB). +* `db_servers` - The list of database servers associated with the Autonomous VM cluster. +* `description` - The user-provided description of the Autonomous VM cluster. +* `display_name` - The display name of the Autonomous VM cluster. +* `domain` - The domain name of the Autonomous VM cluster. +* `exadata_storage_in_tbs_lowest_scaled_value` - The minimum value to which you can scale down the Exadata storage, in TB. +* `hostname` - The hostname of the Autonomous VM cluster. +* `is_mtls_enabled_vm_cluster` - Indicates whether mutual TLS (mTLS) authentication is enabled for the Autonomous VM cluster. +* `license_model` - The Oracle license model that applies to the Autonomous VM cluster. Valid values are LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE. +* `max_acds_lowest_scaled_value` - The minimum value to which you can scale down the maximum number of Autonomous CDBs. +* `memory_per_oracle_compute_unit_in_gbs` - The amount of memory allocated per Oracle Compute Unit, in GB. +* `memory_size_in_gbs` - The total amount of memory allocated to the Autonomous VM cluster, in gigabytes (GB). +* `node_count` - The number of database server nodes in the Autonomous VM cluster. +* `non_provisionable_autonomous_container_databases` - The number of Autonomous CDBs that can't be provisioned because of resource constraints. +* `oci_resource_anchor_name` - The name of the OCI resource anchor associated with this Autonomous VM cluster. +* `oci_url` - The URL for accessing the OCI console page for this Autonomous VM cluster. +* `ocid` - The Oracle Cloud Identifier (OCID) of the Autonomous VM cluster. +* `odb_network_id` - The unique identifier of the ODB network associated with this Autonomous VM cluster. +* `percent_progress` - The progress of the current operation on the Autonomous VM cluster, as a percentage. +* `provisionable_autonomous_container_databases` - The number of Autonomous CDBs that can be provisioned in the Autonomous VM cluster. +* `provisioned_autonomous_container_databases` - The number of Autonomous CDBs currently provisioned in the Autonomous VM cluster. +* `provisioned_cpus` - The number of CPU cores currently provisioned in the Autonomous VM cluster. +* `reclaimable_cpus` - The number of CPU cores that can be reclaimed from terminated or scaled-down Autonomous Databases. +* `reserved_cpus` - The number of CPU cores reserved for system operations and redundancy. +* `scan_listener_port_non_tls` - The SCAN listener port for non-TLS (TCP) protocol. The default is 1521. +* `scan_listener_port_tls` - The SCAN listener port for TLS (TCP) protocol. The default is 2484. +* `shape` - The shape of the Exadata infrastructure for the Autonomous VM cluster. +* `status` - The status of the Autonomous VM cluster. +* `status_reason` - Additional information about the current status of the Autonomous VM cluster. +* `time_database_ssl_certificate_expires` - The expiration date and time of the database SSL certificate. +* `time_ords_certificate_expires` - The expiration date and time of the Oracle REST Data Services (ORDS)certificate. +* `time_zone` - The time zone of the Autonomous VM cluster. +* `total_container_databases` - The total number of Autonomous Container Databases that can be created with the allocated local storage. +* `tags` - A map of tags to assign to the exadata infrastructure. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. +* `maintenance_window` - The maintenance window for the Autonomous VM cluster. diff --git a/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown new file mode 100644 index 000000000000..c18181bcdf3c --- /dev/null +++ b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown @@ -0,0 +1,151 @@ +--- +subcategory: "Oracle Database@AWS" +layout: "AWS: aws_odb_cloud_autonomous_vm_cluster" +page_title: "AWS: aws_odb_cloud_autonomous_vm_cluster" +description: |- + Terraform resource managing cloud autonomous vm cluster in AWS for Oracle Database@AWS. +--- + +# Resource: aws_odb_cloud_autonomous_vm_cluster + +Terraform resource managing cloud autonomous vm cluster in AWS for Oracle Database@AWS. + +You can find out more about Oracle Database@AWS from [User Guide](https://docs.aws.amazon.com/odb/latest/UserGuide/what-is-odb.html). + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_minimum_parameters" { + cloud_exadata_infrastructure_id = "" # refer your exadata infra id + odb_network_id = "" # refer_your_odb_net_id + display_name = "Ofake-avmc-my_avmc" + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + # ids of db server. refer your exa infra. This is a manadatory fileld. Refer your cloud exadata infrastructure for db server id + db_servers = [""] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + preference = "NO_PREFERENCE" + } + +} + + +resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_all_params" { + description = "my first avmc" + time_zone = "UTC" + cloud_exadata_infrastructure_id = "" + odb_network_id = "" + display_name = "Ofake_my avmc" + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = ["", ""] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + days_of_week = [{ name = "MONDAY" }, { name = "TUESDAY" }] + hours_of_day = [4, 16] + lead_time_in_weeks = 3 + months = [{ name = "FEBRUARY" }, { name = "MAY" }, { name = "AUGUST" }, { name = "NOVEMBER" }] + preference = "CUSTOM_PREFERENCE" + weeks_of_month = [2, 4] + } + tags = { + "env" = "dev" + } + +} + +``` + +## Argument Reference + +The following arguments are required: + +* `cloud_exadata_infrastructure_id` - (Required) Exadata infrastructure id. Changing this will force terraform to create new resource. +* `autonomous_data_storage_size_in_tbs` - (Required) The data storage size allocated for Autonomous Databases in the Autonomous VM cluster, in TB. Changing this will force terraform to create new resource. +* `cpu_core_count_per_node` - (Required) The number of CPU cores enabled per node in the Autonomous VM cluster. Changing this will force terraform to create new resource. +* `db_servers` - (Required) The database servers in the Autonomous VM cluster. Changing this will force terraform to create new resource. +* `display_name` - (Required) The display name of the Autonomous VM cluster. Changing this will force terraform to create new resource. +* `memory_per_oracle_compute_unit_in_gbs` - (Required) The amount of memory allocated per Oracle Compute Unit, in GB. Changing this will force terraform to create new resource. +* `odb_network_id` - (Required) The unique identifier of the ODB network associated with this Autonomous VM Cluster. Changing this will force terraform to create new resource. +* `scan_listener_port_non_tls` - (Required) The SCAN listener port for non-TLS (TCP) protocol. The default is 1521. Changing this will force terraform to create new resource. +* `scan_listener_port_tls` - (Required) The SCAN listener port for TLS (TCP) protocol. The default is 2484. Changing this will force terraform to create new resource. +* `total_container_databases` - (Required) The total number of Autonomous Container Databases that can be created with the allocated local storage. Changing this will force terraform to create new resource. +* `maintenance_window` - (Required) The maintenance window of the Autonomous VM cluster. Changing this will force terraform to create new resource. + +The following arguments are optional: + +* `description` - (Optional) The description of the Autonomous VM cluster. +* `is_mtls_enabled_vm_cluster` - (Optional) Indicates whether mutual TLS (mTLS) authentication is enabled for the Autonomous VM cluster. Changing this will force terraform to create new resource. +* `license_model` - (Optional) The license model for the Autonomous VM cluster. Valid values are LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE. Changing this will force terraform to create new resource. +* `time_zone` - (Optional) The time zone of the Autonomous VM cluster. Changing this will force terraform to create new resource. +* `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference). +* `tags` - (Optional) A map of tags to assign to the exadata infrastructure. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. + +### maintenance_window + +The following arguments are required: + +* `preference` - (Required) The preference for the maintenance window scheduling. + +The following arguments are optional: + +* `days_of_week` - (Optional) The days of the week when maintenance can be performed. +* `hours_of_day` - (Optional) The hours of the day when maintenance can be performed. +* `lead_time_in_weeks` - (Optional) The lead time in weeks before the maintenance window. +* `months` - (Optional) The months when maintenance can be performed. +* `weeks_of_month` - (Optional) Indicates whether to skip release updates during maintenance. + + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +# Computed Attributes for Autonomous VM Cluster Resource + +* `arn` - The Amazon Resource Name (ARN) for the Exadata infrastructure. +* `autonomous_data_storage_percentage` - The progress of the current operation on the Autonomous VM cluster, as a percentage. +* `available_autonomous_data_storage_size_in_tbs` - The available data storage space for Autonomous Databases in the Autonomous VM cluster, in TB. +* `available_container_databases` - The number of Autonomous CDBs that you can create with the currently available storage. +* `available_cpus` - The number of CPU cores available for allocation to Autonomous Databases. +* `compute_model` - The compute model of the Autonomous VM cluster: ECPU or OCPU. +* `cpu_core_count` - The total number of CPU cores in the Autonomous VM cluster. +* `cpu_percentage` - The percentage of total CPU cores currently in use in the Autonomous VM cluster. +* `created_at` - The date and time when the Autonomous VM cluster was created. +* `data_storage_size_in_gbs` - The total data storage allocated to the Autonomous VM cluster, in GB. +* `data_storage_size_in_tbs` - The total data storage allocated to the Autonomous VM cluster, in TB. +* `odb_node_storage_size_in_gbs` - The local node storage allocated to the Autonomous VM cluster, in gigabytes (GB). +* `domain` - The domain name of the Autonomous VM cluster. +* `exadata_storage_in_tbs_lowest_scaled_value` - The minimum value to which you can scale down the Exadata storage, in TB. +* `hostname` - The hostname of the Autonomous VM cluster. +* `license_model` - The license model for the Autonomous VM cluster. Valid values are LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE. +* `max_acds_lowest_scaled_value` - The minimum value to which you can scale down the maximum number of Autonomous CDBs. +* `memory_size_in_gbs` - The total amount of memory allocated to the Autonomous VM cluster, in gigabytes(GB). +* `node_count` - The number of database server nodes in the Autonomous VM cluster. +* `non_provisionable_autonomous_container_databases` - The number of Autonomous CDBs that can't be provisioned because of resource constraints. +* `oci_resource_anchor_name` - The name of the OCI resource anchor associated with this Autonomous VM cluster. +* `oci_url` - The URL for accessing the OCI console page for this Autonomous VM cluster. +* `ocid` - The Oracle Cloud Identifier (OCID) of the Autonomous VM cluster. +* `percent_progress` - The progress of the current operation on the Autonomous VM cluster, as a percentage. +* `provisionable_autonomous_container_databases` - The number of Autonomous CDBs that can be provisioned in the Autonomous VM cluster. +* `provisioned_autonomous_container_databases` - The number of Autonomous CDBs currently provisioned in the Autonomous VM cluster. +* `provisioned_cpus` - The number of CPUs provisioned in the Autonomous VM cluster. +* `reclaimable_cpus` - The number of CPU cores that can be reclaimed from terminated or scaled-down Autonomous Databases. +* `reserved_cpus` - The number of CPU cores reserved for system operations and redundancy. +* `shape` - The shape of the Exadata infrastructure for the Autonomous VM cluster. +* `status` - The status of the Autonomous VM cluster. Possible values include CREATING, AVAILABLE, UPDATING, DELETING, DELETED, FAILED. +* `status_reason` - Additional information about the current status of the Autonomous VM cluster. +* `time_zone` - The time zone of the Autonomous VM cluster. +* `time_ords_certificate_expires` - The expiration date and time of the ORDS certificate. +* `time_database_ssl_certificate_expires` - The expiration date and time of the database SSL certificate. +* `tags_all` - The combined set of user-defined and provider-defined tags. From ff45640df0b342dcb15e67a4578121686dfc8b5c Mon Sep 17 00:00:00 2001 From: Asim Date: Fri, 29 Aug 2025 22:15:32 +0100 Subject: [PATCH 12/42] fix linter issues --- ..._autonomous_vm_cluster_data_source_test.go | 7 +++--- ..._cloud_autonomous_vm_cluster.html.markdown | 22 ++++++------------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go index d01c24a71527..3a2703c51764 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go @@ -9,7 +9,6 @@ import ( "testing" "github.com/aws/aws-sdk-go-v2/service/odb" - odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -39,8 +38,8 @@ func TestAccODBCloudAutonomousVmClusterDataSource_basic(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } - var avmc1 odbtypes.CloudAutonomousVmCluster - dataSourceName := "data.aws_odb_cloud_autonomous_vm_cluster.test" + avmcResource := "aws_odb_cloud_autonomous_vm_cluster.test" + avmcDataSource := "data.aws_odb_cloud_autonomous_vm_cluster.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { @@ -54,7 +53,7 @@ func TestAccODBCloudAutonomousVmClusterDataSource_basic(t *testing.T) { { Config: autonomousVMClusterDSTestEntity.avmcBasic(), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, names.AttrDisplayName, *avmc1.DisplayName), + resource.TestCheckResourceAttrPair(avmcResource, names.AttrID, avmcDataSource, names.AttrID), ), }, }, diff --git a/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown index c18181bcdf3c..e18f28162684 100644 --- a/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown +++ b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown @@ -94,24 +94,16 @@ The following arguments are optional: ### maintenance_window -The following arguments are required: - -* `preference` - (Required) The preference for the maintenance window scheduling. - -The following arguments are optional: - -* `days_of_week` - (Optional) The days of the week when maintenance can be performed. -* `hours_of_day` - (Optional) The hours of the day when maintenance can be performed. -* `lead_time_in_weeks` - (Optional) The lead time in weeks before the maintenance window. -* `months` - (Optional) The months when maintenance can be performed. -* `weeks_of_month` - (Optional) Indicates whether to skip release updates during maintenance. - +* `preference` - (Required) The preference for the maintenance window scheduling. Changing this will force terraform to create new resource. +* `days_of_week` - (Optional) The days of the week when maintenance can be performed. Changing this will force terraform to create new resource. +* `hours_of_day` - (Optional) The hours of the day when maintenance can be performed. Changing this will force terraform to create new resource. +* `lead_time_in_weeks` - (Optional) The lead time in weeks before the maintenance window. Changing this will force terraform to create new resource. +* `months` - (Optional) The months when maintenance can be performed. Changing this will force terraform to create new resource. +* `weeks_of_month` - (Optional) Indicates whether to skip release updates during maintenance. Changing this will force terraform to create new resource. ## Attribute Reference -This data source exports the following attributes in addition to the arguments above: - -# Computed Attributes for Autonomous VM Cluster Resource +This resource exports the following attributes in addition to the arguments above: * `arn` - The Amazon Resource Name (ARN) for the Exadata infrastructure. * `autonomous_data_storage_percentage` - The progress of the current operation on the Autonomous VM cluster, as a percentage. From 6491285bf82a436a9754d2fd7c13fa24dc568c96 Mon Sep 17 00:00:00 2001 From: Asim Date: Mon, 1 Sep 2025 11:11:37 +0100 Subject: [PATCH 13/42] reverted changes made to names_data.hcl. Setting the partial state if error occurs. --- internal/service/odb/cloud_autonomous_vm_cluster.go | 2 ++ names/data/names_data.hcl | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index 7a0d96344874..aab64ea7a041 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -5,6 +5,7 @@ package odb import ( "context" "errors" + "github.com/hashicorp/terraform-plugin-framework/path" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -427,6 +428,7 @@ func (r *resourceCloudAutonomousVmCluster) Create(ctx context.Context, req resou createTimeout := r.CreateTimeout(ctx, plan.Timeouts) createdAVMC, err := waitCloudAutonomousVmClusterCreated(ctx, conn, *out.CloudAutonomousVmClusterId, createTimeout) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(names.AttrID), aws.ToString(out.CloudAutonomousVmClusterId))...) if err != nil { resp.Diagnostics.AddError( create.ProblemStandardMessage(names.ODB, create.ErrActionWaitingForCreation, ResNameCloudAutonomousVmCluster, plan.DisplayName.ValueString(), err), diff --git a/names/data/names_data.hcl b/names/data/names_data.hcl index 10685ba3c109..da2600fbf852 100644 --- a/names/data/names_data.hcl +++ b/names/data/names_data.hcl @@ -9520,4 +9520,4 @@ service "evs" { provider_package_correct = "evs" doc_prefix = ["evs_"] brand = "Amazon" -} +} \ No newline at end of file From 6d56efe4caae182e09830c2e7efa69a9314ae04c Mon Sep 17 00:00:00 2001 From: Asim Date: Tue, 2 Sep 2025 15:31:28 +0100 Subject: [PATCH 14/42] fixed the linter : grouping of imports --- internal/service/odb/cloud_autonomous_vm_cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index aab64ea7a041..8eb66c4c4134 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -5,7 +5,6 @@ package odb import ( "context" "errors" - "github.com/hashicorp/terraform-plugin-framework/path" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -15,6 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" From c1b796ba4b3f6f6fc20f69c6b2908fbe99d1fac5 Mon Sep 17 00:00:00 2001 From: Asim Date: Wed, 3 Sep 2025 12:58:11 +0100 Subject: [PATCH 15/42] review feedback addressed. --- .changelog/{43650.txt => 43809.txt} | 0 .../odb/cloud_autonomous_vm_cluster.go | 43 ------------------- 2 files changed, 43 deletions(-) rename .changelog/{43650.txt => 43809.txt} (100%) diff --git a/.changelog/43650.txt b/.changelog/43809.txt similarity index 100% rename from .changelog/43650.txt rename to .changelog/43809.txt diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index 8eb66c4c4134..873077edcc6a 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -154,7 +154,6 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou Optional: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), - stringplanmodifier.UseStateForUnknown(), }, Description: "The description of the Autonomous VM cluster.", }, @@ -470,32 +469,6 @@ func (r *resourceCloudAutonomousVmCluster) Read(ctx context.Context, req resourc resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) } -func (r *resourceCloudAutonomousVmCluster) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan, state cloudAutonomousVmClusterResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - conn := r.Meta().ODBClient(ctx) - - updateTimeout := r.UpdateTimeout(ctx, plan.Timeouts) - updatedAVMC, err := waitCloudAutonomousVmClusterUpdated(ctx, conn, state.CloudAutonomousVmClusterId.ValueString(), updateTimeout) - - if err != nil { - resp.Diagnostics.AddError( - create.ProblemStandardMessage(names.ODB, create.ErrActionWaitingForUpdate, ResNameCloudAutonomousVmCluster, state.CloudAutonomousVmClusterId.String(), err), - err.Error(), - ) - return - } - resp.Diagnostics.Append(flex.Flatten(ctx, updatedAVMC, &plan)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - func (r *resourceCloudAutonomousVmCluster) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { conn := r.Meta().ODBClient(ctx) @@ -549,22 +522,6 @@ func waitCloudAutonomousVmClusterCreated(ctx context.Context, conn *odb.Client, return nil, err } -func waitCloudAutonomousVmClusterUpdated(ctx context.Context, conn *odb.Client, id string, timeout time.Duration) (*odbtypes.CloudAutonomousVmCluster, error) { - stateConf := &retry.StateChangeConf{ - Pending: enum.Slice(odbtypes.ResourceStatusUpdating), - Target: enum.Slice(odbtypes.ResourceStatusAvailable, odbtypes.ResourceStatusFailed), - Refresh: statusCloudAutonomousVmCluster(ctx, conn, id), - Timeout: timeout, - } - - outputRaw, err := stateConf.WaitForStateContext(ctx) - if out, ok := outputRaw.(*odbtypes.CloudAutonomousVmCluster); ok { - return out, err - } - - return nil, err -} - func waitCloudAutonomousVmClusterDeleted(ctx context.Context, conn *odb.Client, id string, timeout time.Duration) (*odbtypes.CloudAutonomousVmCluster, error) { stateConf := &retry.StateChangeConf{ Pending: enum.Slice(odbtypes.ResourceStatusTerminating), From b3f40ebd478acd15082962c95e80e16bd41ab7b3 Mon Sep 17 00:00:00 2001 From: Asim Date: Thu, 11 Sep 2025 10:09:56 +0100 Subject: [PATCH 16/42] updated copyright header --- examples/odb/autonomous_vm_cluster.tf | 3 ++- internal/service/odb/cloud_autonomous_vm_cluster.go | 3 ++- .../service/odb/cloud_autonomous_vm_cluster_data_source.go | 3 ++- .../odb/cloud_autonomous_vm_cluster_data_source_test.go | 3 ++- internal/service/odb/cloud_autonomous_vm_cluster_test.go | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/examples/odb/autonomous_vm_cluster.tf b/examples/odb/autonomous_vm_cluster.tf index 66ce3eeab83f..920237d77c56 100644 --- a/examples/odb/autonomous_vm_cluster.tf +++ b/examples/odb/autonomous_vm_cluster.tf @@ -1,4 +1,5 @@ -# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 # Autonomous VM Cluster with default maintenance window and minimum parameters resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_minimum_parameters" { diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index 873077edcc6a..2f7adf8ce41b 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -1,4 +1,5 @@ -// Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package odb diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go index 16f2c917113e..d21456c05544 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go @@ -1,4 +1,5 @@ -// Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package odb diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go index 3a2703c51764..172ffd5f3831 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go @@ -1,4 +1,5 @@ -// Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package odb_test diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go index c5357ddbe271..b9ef4784286e 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster_test.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -1,4 +1,5 @@ -// Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 package odb_test From 12dc5d918a13114df9d9deb3af439a7db5eb16a2 Mon Sep 17 00:00:00 2001 From: Asim Date: Thu, 11 Sep 2025 11:44:43 +0100 Subject: [PATCH 17/42] fixed documentation --- ..._cloud_autonomous_vm_cluster.html.markdown | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown index e18f28162684..7183e4bae392 100644 --- a/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown +++ b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown @@ -141,3 +141,28 @@ This resource exports the following attributes in addition to the arguments abov * `time_ords_certificate_expires` - The expiration date and time of the ORDS certificate. * `time_database_ssl_certificate_expires` - The expiration date and time of the database SSL certificate. * `tags_all` - The combined set of user-defined and provider-defined tags. + +## Timeouts + +[Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): + +* `create` - (Default `24h`) +* `update` - (Default `24h`) +* `delete` - (Default `24h`) + +## Import + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import OpenSearch Ingestion Pipeline using the `id`. For example: + +```terraform +import { + to = aws_odb_cloud_autonomous_vm_cluster.example + id = "example" +} +``` + +Using `terraform import`, import Odb Network using the `id`. For example: + +```console +% terraform import aws_odb_cloud_autonomous_vm_cluster.example example +``` \ No newline at end of file From c1c1611460bfc53c56c47b206d2679fcc590bd95 Mon Sep 17 00:00:00 2001 From: Asim Date: Thu, 11 Sep 2025 11:57:23 +0100 Subject: [PATCH 18/42] fixed documentation --- website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown index 7183e4bae392..59f492ca557a 100644 --- a/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown +++ b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown @@ -161,7 +161,7 @@ import { } ``` -Using `terraform import`, import Odb Network using the `id`. For example: +Using `terraform import`, import cloud autonomous vm cluster `id`. For example: ```console % terraform import aws_odb_cloud_autonomous_vm_cluster.example example From 5340ad386eb65aada7d6051afd0794ed50e5d85d Mon Sep 17 00:00:00 2001 From: Asim Date: Thu, 11 Sep 2025 18:44:32 +0100 Subject: [PATCH 19/42] fixed linter --- website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown index 59f492ca557a..391a2b013a5b 100644 --- a/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown +++ b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown @@ -165,4 +165,4 @@ Using `terraform import`, import cloud autonomous vm cluster `id`. For example: ```console % terraform import aws_odb_cloud_autonomous_vm_cluster.example example -``` \ No newline at end of file +``` From 5cd18b984fe52c717c0c4ba7ecf6e4e1258d9be6 Mon Sep 17 00:00:00 2001 From: Asim Date: Fri, 12 Sep 2025 12:23:24 +0100 Subject: [PATCH 20/42] Maintenance Window made mandatory. --- internal/service/odb/cloud_autonomous_vm_cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go index 2f7adf8ce41b..e330f78fe481 100644 --- a/internal/service/odb/cloud_autonomous_vm_cluster.go +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -331,7 +331,7 @@ func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resou CustomType: fwtypes.NewListNestedObjectTypeOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel](ctx), Validators: []validator.List{ listvalidator.SizeAtMost(1), - listvalidator.SizeAtLeast(1), + listvalidator.IsRequired(), }, PlanModifiers: []planmodifier.List{ listplanmodifier.RequiresReplace(), From c2b9d0849af0dacbe0e0627063a4eeb61c5b6b91 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Fri, 12 Sep 2025 11:51:31 -0700 Subject: [PATCH 21/42] Correctly sets `id` for `aws_api_gateway_domain_name` with private endpoints --- internal/service/apigateway/sweep.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/apigateway/sweep.go b/internal/service/apigateway/sweep.go index 145b106f66b1..7445e252906d 100644 --- a/internal/service/apigateway/sweep.go +++ b/internal/service/apigateway/sweep.go @@ -305,7 +305,7 @@ func sweepDomainNames(region string) error { for _, v := range page.Items { r := resourceDomainName() d := r.Data(nil) - d.SetId(aws.ToString(v.DomainName)) + d.SetId(domainNameCreateResourceID(aws.ToString(v.DomainName), aws.ToString(v.DomainNameId))) sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } From acf6406d25d5547a1d5d482918c705a4c59e0e16 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Fri, 12 Sep 2025 12:12:12 -0700 Subject: [PATCH 22/42] Lists all `aws_acm_certificate` key types --- internal/service/acm/sweep.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/service/acm/sweep.go b/internal/service/acm/sweep.go index d8e4fe21f51e..90d8ff84b51c 100644 --- a/internal/service/acm/sweep.go +++ b/internal/service/acm/sweep.go @@ -9,7 +9,9 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/acm" + awstypes "github.com/aws/aws-sdk-go-v2/service/acm/types" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/enum" "github.com/hashicorp/terraform-provider-aws/internal/sweep" "github.com/hashicorp/terraform-provider-aws/internal/sweep/awsv2" ) @@ -48,7 +50,12 @@ func sweepCertificates(region string) error { conn := client.ACMClient(ctx) var sweepResources []sweep.Sweepable - input := acm.ListCertificatesInput{} + input := acm.ListCertificatesInput{ + Includes: &awstypes.Filters{ + // By default, ListCertificates only returns RSA_1024 and RSA_2048 certificates + KeyTypes: enum.EnumValues[awstypes.KeyAlgorithm](), + }, + } pages := acm.NewListCertificatesPaginator(conn, &input) for pages.HasMorePages() { page, err := pages.NextPage(ctx) From 83cc9e3918619af732751c73587835b14b9c070f Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Fri, 12 Sep 2025 17:17:44 -0700 Subject: [PATCH 23/42] Adds `AmazonBedrockExecutionRoleForAgents` prefix to `aws_iam_role` sweeper allow-list --- internal/service/iam/sweep.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/service/iam/sweep.go b/internal/service/iam/sweep.go index 15cf6ef25709..16622a6c92cd 100644 --- a/internal/service/iam/sweep.go +++ b/internal/service/iam/sweep.go @@ -59,6 +59,7 @@ func RegisterSweepers() { Dependencies: []string{ "aws_auditmanager_assessment", "aws_batch_compute_environment", + "aws_bedrockagent_agent", "aws_cloudformation_stack_set_instance", "aws_cognito_user_pool", "aws_config_configuration_aggregator", @@ -661,6 +662,7 @@ func roleNameFilter(name string) bool { // exhaustive list. prefixes := []string{ "another_rds", + "AmazonBedrockExecutionRoleForAgents", // Required role name prefix "AmazonComprehendServiceRole-", "aws_batch_service_role", "aws_elastictranscoder_pipeline_tf_test", From 562f812200b8f934ead90e183fb0b337de463fda Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Fri, 12 Sep 2025 17:39:46 -0700 Subject: [PATCH 24/42] Handles spurious `types.InvalidRequestException` when not found --- internal/service/athena/data_catalog.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/service/athena/data_catalog.go b/internal/service/athena/data_catalog.go index 2a8a35ca4aba..7824b3a24410 100644 --- a/internal/service/athena/data_catalog.go +++ b/internal/service/athena/data_catalog.go @@ -198,6 +198,9 @@ func resourceDataCatalogDelete(ctx context.Context, d *schema.ResourceData, meta if errs.IsA[*types.ResourceNotFoundException](err) { return diags } + if errs.IsAErrorMessageContains[*types.InvalidRequestException](err, "was not found") { + return diags + } if err != nil { return sdkdiag.AppendErrorf(diags, "deleting Athena Data Catalog (%s): %s", d.Id(), err) From cab00d92afd850648056b1db071b5f78818e849d Mon Sep 17 00:00:00 2001 From: tabito Date: Sat, 13 Sep 2025 13:16:23 +0900 Subject: [PATCH 25/42] Add aws_billing_view data source --- internal/service/billing/views_data_source.go | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 internal/service/billing/views_data_source.go diff --git a/internal/service/billing/views_data_source.go b/internal/service/billing/views_data_source.go new file mode 100644 index 000000000000..f1f8b535bce8 --- /dev/null +++ b/internal/service/billing/views_data_source.go @@ -0,0 +1,103 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package billing + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/service/billing" + awstypes "github.com/aws/aws-sdk-go-v2/service/billing/types" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/smerr" +) + +// @FrameworkDataSource("aws_billing_views", name="Views") +func newDataSourceViews(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceViews{}, nil +} + +const ( + DSNameViews = "Views Data Source" +) + +type dataSourceViews struct { + framework.DataSourceWithModel[dataSourceViewsModel] +} + +func (d *dataSourceViews) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "billing_view_types": schema.ListAttribute{ + CustomType: fwtypes.ListOfStringEnumType[awstypes.BillingViewType](), + Optional: true, + ElementType: types.StringType, + }, + "billing_view": framework.ResourceComputedListOfObjectsAttribute[dataSourceBillingViewModel](ctx, nil, nil), + }, + } +} + +func (d *dataSourceViews) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + conn := d.Meta().BillingClient(ctx) + + var data dataSourceViewsModel + smerr.EnrichAppend(ctx, &resp.Diagnostics, req.Config.Get(ctx, &data)) + if resp.Diagnostics.HasError() { + return + } + + var billingViewTypes []awstypes.BillingViewType + smerr.EnrichAppend(ctx, &resp.Diagnostics, data.BillingViewTypes.ElementsAs(ctx, &billingViewTypes, false)) + if resp.Diagnostics.HasError() { + return + } + + out, err := findViewsByBillingViewTypes(ctx, conn, billingViewTypes) + if err != nil { + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, data.BillingViewTypes.String()) + return + } + + smerr.EnrichAppend(ctx, &resp.Diagnostics, flex.Flatten(ctx, out, &data.BillingView, flex.WithFieldNamePrefix("Views")), smerr.ID, data.BillingViewTypes.String()) + if resp.Diagnostics.HasError() { + return + } + + smerr.EnrichAppend(ctx, &resp.Diagnostics, resp.State.Set(ctx, &data), smerr.ID, data.BillingViewTypes.String()) +} + +func findViewsByBillingViewTypes(ctx context.Context, conn *billing.Client, billingViewTypes []awstypes.BillingViewType) ([]awstypes.BillingViewListElement, error) { + var results []awstypes.BillingViewListElement + + input := &billing.ListBillingViewsInput{ + BillingViewTypes: billingViewTypes, + } + paginator := billing.NewListBillingViewsPaginator(conn, input) + for paginator.HasMorePages() { + page, err := paginator.NextPage(ctx) + if err != nil { + return nil, err + } + results = append(results, page.BillingViews...) + } + return results, nil +} + +type dataSourceViewsModel struct { + BillingViewTypes fwtypes.ListOfStringEnum[awstypes.BillingViewType] `tfsdk:"billing_view_types"` + BillingView fwtypes.ListNestedObjectValueOf[dataSourceBillingViewModel] `tfsdk:"billing_view"` +} + +type dataSourceBillingViewModel struct { + ARN types.String `tfsdk:"arn"` + BillingViewType types.String `tfsdk:"billing_view_type"` + Description types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + OwnerAccountId types.String `tfsdk:"owner_account_id"` +} From eb1151d7abbc7ecd1b2c71f47e9981d5d8e9a922 Mon Sep 17 00:00:00 2001 From: tabito Date: Sat, 13 Sep 2025 13:17:02 +0900 Subject: [PATCH 26/42] add an acceptance test for new data source aws_billing_views --- .../service/billing/views_data_source_test.go | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 internal/service/billing/views_data_source_test.go diff --git a/internal/service/billing/views_data_source_test.go b/internal/service/billing/views_data_source_test.go new file mode 100644 index 000000000000..815a82e8e923 --- /dev/null +++ b/internal/service/billing/views_data_source_test.go @@ -0,0 +1,45 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package billing_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccBillingViewsDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + + dataSourceName := "data.aws_billing_views.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.BillingServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccViewsDataSourceConfig_basic(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "billing_view.#", "1"), + acctest.CheckResourceAttrGlobalARN(ctx, dataSourceName, "billing_view.0.arn", "billing", "billingview/primary"), + resource.TestCheckResourceAttr(dataSourceName, "billing_view.0.billing_view_type", "PRIMARY"), + resource.TestCheckResourceAttr(dataSourceName, "billing_view.0.name", "Primary View"), + ), + }, + }, + }) +} + +func testAccViewsDataSourceConfig_basic() string { + return ` +data "aws_billing_views" "test" { + billing_view_types = ["PRIMARY"] +} +` +} From 4b0f22c2c20e99f91792b3773302f6242a7f801b Mon Sep 17 00:00:00 2001 From: tabito Date: Sat, 13 Sep 2025 13:18:09 +0900 Subject: [PATCH 27/42] make gen --- internal/service/billing/service_package_gen.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/service/billing/service_package_gen.go b/internal/service/billing/service_package_gen.go index 84aedd7d64f0..5e30758bd55f 100644 --- a/internal/service/billing/service_package_gen.go +++ b/internal/service/billing/service_package_gen.go @@ -26,6 +26,12 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*inttypes.S Name: "Service Account", Region: unique.Make(inttypes.ResourceRegionDisabled()), }, + { + Factory: newDataSourceViews, + TypeName: "aws_billing_views", + Name: "Views", + Region: unique.Make(inttypes.ResourceRegionDisabled()), + }, } } From 5d250d557b1260acaa2e392862139c0b54d1fa17 Mon Sep 17 00:00:00 2001 From: tabito Date: Sat, 13 Sep 2025 13:18:17 +0900 Subject: [PATCH 28/42] Add the documentation for new data source aws_billing_views --- website/docs/d/billing_views.html.markdown | 53 ++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 website/docs/d/billing_views.html.markdown diff --git a/website/docs/d/billing_views.html.markdown b/website/docs/d/billing_views.html.markdown new file mode 100644 index 000000000000..7933857e18ef --- /dev/null +++ b/website/docs/d/billing_views.html.markdown @@ -0,0 +1,53 @@ +--- +subcategory: "Billing" +layout: "aws" +page_title: "AWS: aws_billing_views" +description: |- + Retrieve a list of AWS Billing Views. +--- + +# Data Source: aws_billing_views + +Provides details about an AWS Billing Views. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_billing_views" "example" { + billing_view_types = ["PRIMARY"] +} + +output "primary_view_arn_by_types" { + value = data.aws_billing_views.example.billing_view[0].arn +} +``` + +```terraform +data "aws_billing_views" "example" {} + +output "view_arns" { + value = [for view in data.aws_billing_views.example.billing_view : view.arn] +} + +output "primary_view_arn_by_name" { + value = [for view in data.aws_billing_views.example.billing_view : view.arn if view.name == "Primary View"][0] +} +``` + +## Argument Reference + +The following arguments are optional: + +* `billing_view_types` - (Optional) List of billing view types to retrieve. Valid values are `PRIMARY`, `BILLING_GROUP`, `CUSTOM`. + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `billing_view` - List of billing view objects with the following attributes: + * `arn` - ARN of the billing view. + * `description` - Description of the billing view. + * `name` - Name of the billing view. + * `owner_account_id` - Account ID of the billing view owner. From b542c6d0de6db6d2368f933ef7b34afc98457fd8 Mon Sep 17 00:00:00 2001 From: tabito Date: Sat, 13 Sep 2025 13:39:04 +0900 Subject: [PATCH 29/42] add changelog --- .changelog/44272.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/44272.txt diff --git a/.changelog/44272.txt b/.changelog/44272.txt new file mode 100644 index 000000000000..52a9f36bd26e --- /dev/null +++ b/.changelog/44272.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_billing_view +``` From 5b590a35f5b4d8c7103f55abaf6921ae6e34eaaf Mon Sep 17 00:00:00 2001 From: tabito Date: Sat, 13 Sep 2025 13:44:01 +0900 Subject: [PATCH 30/42] Pass BillingViewTypes to the API only when it is specified --- internal/service/billing/views_data_source.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/service/billing/views_data_source.go b/internal/service/billing/views_data_source.go index f1f8b535bce8..d1776070d767 100644 --- a/internal/service/billing/views_data_source.go +++ b/internal/service/billing/views_data_source.go @@ -75,9 +75,12 @@ func (d *dataSourceViews) Read(ctx context.Context, req datasource.ReadRequest, func findViewsByBillingViewTypes(ctx context.Context, conn *billing.Client, billingViewTypes []awstypes.BillingViewType) ([]awstypes.BillingViewListElement, error) { var results []awstypes.BillingViewListElement - input := &billing.ListBillingViewsInput{ - BillingViewTypes: billingViewTypes, + input := &billing.ListBillingViewsInput{} + + if len(billingViewTypes) > 0 { + input.BillingViewTypes = billingViewTypes } + paginator := billing.NewListBillingViewsPaginator(conn, input) for paginator.HasMorePages() { page, err := paginator.NextPage(ctx) From 63c84cc1ec5999fe94b476aefefbb4757a0a0cb1 Mon Sep 17 00:00:00 2001 From: tabito Date: Sat, 13 Sep 2025 13:52:44 +0900 Subject: [PATCH 31/42] Add an acceptance test for no-argument case --- .../service/billing/views_data_source_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal/service/billing/views_data_source_test.go b/internal/service/billing/views_data_source_test.go index 815a82e8e923..7abc160db527 100644 --- a/internal/service/billing/views_data_source_test.go +++ b/internal/service/billing/views_data_source_test.go @@ -32,6 +32,15 @@ func TestAccBillingViewsDataSource_basic(t *testing.T) { resource.TestCheckResourceAttr(dataSourceName, "billing_view.0.name", "Primary View"), ), }, + { + Config: testAccViewsDataSourceConfig_noArguments(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckTypeSetElemNestedAttrs(dataSourceName, "billing_view.*", map[string]string{ + "billing_view_type": "PRIMARY", + "name": "Primary View", + }), + ), + }, }, }) } @@ -43,3 +52,9 @@ data "aws_billing_views" "test" { } ` } + +func testAccViewsDataSourceConfig_noArguments() string { + return ` +data "aws_billing_views" "test" {} +` +} From 586d8faf2fd1c7aa58d878653a2967137f0c2fbf Mon Sep 17 00:00:00 2001 From: tabito Date: Sat, 13 Sep 2025 13:55:20 +0900 Subject: [PATCH 32/42] fix changelog --- .changelog/44272.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/44272.txt b/.changelog/44272.txt index 52a9f36bd26e..c4394c9254e1 100644 --- a/.changelog/44272.txt +++ b/.changelog/44272.txt @@ -1,3 +1,3 @@ ```release-note:new-data-source -aws_billing_view +aws_billing_views ``` From f1eac7fe591c2a665f500fe3cd9bc7e79a19c7f7 Mon Sep 17 00:00:00 2001 From: tabito Date: Sat, 13 Sep 2025 13:57:03 +0900 Subject: [PATCH 33/42] Rename the find function and fix to create a struct on the stack --- internal/service/billing/views_data_source.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/service/billing/views_data_source.go b/internal/service/billing/views_data_source.go index d1776070d767..c6763f2b3404 100644 --- a/internal/service/billing/views_data_source.go +++ b/internal/service/billing/views_data_source.go @@ -58,7 +58,7 @@ func (d *dataSourceViews) Read(ctx context.Context, req datasource.ReadRequest, return } - out, err := findViewsByBillingViewTypes(ctx, conn, billingViewTypes) + out, err := findViewsByViewTypes(ctx, conn, billingViewTypes) if err != nil { smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, data.BillingViewTypes.String()) return @@ -72,16 +72,16 @@ func (d *dataSourceViews) Read(ctx context.Context, req datasource.ReadRequest, smerr.EnrichAppend(ctx, &resp.Diagnostics, resp.State.Set(ctx, &data), smerr.ID, data.BillingViewTypes.String()) } -func findViewsByBillingViewTypes(ctx context.Context, conn *billing.Client, billingViewTypes []awstypes.BillingViewType) ([]awstypes.BillingViewListElement, error) { +func findViewsByViewTypes(ctx context.Context, conn *billing.Client, billingViewTypes []awstypes.BillingViewType) ([]awstypes.BillingViewListElement, error) { var results []awstypes.BillingViewListElement - input := &billing.ListBillingViewsInput{} + input := billing.ListBillingViewsInput{} if len(billingViewTypes) > 0 { input.BillingViewTypes = billingViewTypes } - paginator := billing.NewListBillingViewsPaginator(conn, input) + paginator := billing.NewListBillingViewsPaginator(conn, &input) for paginator.HasMorePages() { page, err := paginator.NextPage(ctx) if err != nil { From ad5abd8144f9f270a740f892384d04780350b966 Mon Sep 17 00:00:00 2001 From: tabito Date: Sat, 13 Sep 2025 14:19:21 +0900 Subject: [PATCH 34/42] Replace "name" with names.AttrName --- internal/service/billing/views_data_source_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/billing/views_data_source_test.go b/internal/service/billing/views_data_source_test.go index 7abc160db527..4058dea241a5 100644 --- a/internal/service/billing/views_data_source_test.go +++ b/internal/service/billing/views_data_source_test.go @@ -37,7 +37,7 @@ func TestAccBillingViewsDataSource_basic(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckTypeSetElemNestedAttrs(dataSourceName, "billing_view.*", map[string]string{ "billing_view_type": "PRIMARY", - "name": "Primary View", + names.AttrName: "Primary View", }), ), }, From f4febdb99c59a4016178f2cded3e7bb998e5b8e5 Mon Sep 17 00:00:00 2001 From: tabito Date: Tue, 16 Sep 2025 23:18:36 +0900 Subject: [PATCH 35/42] Return an empty object when the first element is nil --- internal/service/sagemaker/endpoint_configuration.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/service/sagemaker/endpoint_configuration.go b/internal/service/sagemaker/endpoint_configuration.go index 544ed48baefd..c64f2ad67fc0 100644 --- a/internal/service/sagemaker/endpoint_configuration.go +++ b/internal/service/sagemaker/endpoint_configuration.go @@ -1107,6 +1107,9 @@ func expandEndpointConfigNotificationConfig(configured []any) *awstypes.AsyncInf if len(configured) == 0 { return nil } + if configured[0] == nil { + return &awstypes.AsyncInferenceNotificationConfig{} + } m := configured[0].(map[string]any) From 910081c93edd5215791cc3744bde7f0b812fd723 Mon Sep 17 00:00:00 2001 From: tabito Date: Tue, 16 Sep 2025 23:19:33 +0900 Subject: [PATCH 36/42] Add a step in the acc test to check empty notification_config is allowed --- .../sagemaker/endpoint_configuration_test.go | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/internal/service/sagemaker/endpoint_configuration_test.go b/internal/service/sagemaker/endpoint_configuration_test.go index 50b6d1dbb26a..753f82681527 100644 --- a/internal/service/sagemaker/endpoint_configuration_test.go +++ b/internal/service/sagemaker/endpoint_configuration_test.go @@ -769,6 +769,24 @@ func TestAccSageMakerEndpointConfiguration_Async_notif(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + Config: testAccEndpointConfigurationConfig_asyncNotifEmpty(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckEndpointConfigurationExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), + resource.TestCheckResourceAttr(resourceName, "async_inference_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "async_inference_config.0.client_config.#", "0"), + resource.TestCheckResourceAttr(resourceName, "async_inference_config.0.output_config.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "async_inference_config.0.output_config.0.s3_output_path"), + resource.TestCheckResourceAttr(resourceName, "async_inference_config.0.output_config.0.notification_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "async_inference_config.0.output_config.0.notification_config.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -1523,6 +1541,46 @@ resource "aws_sagemaker_endpoint_configuration" "test" { `, rName)) } +func testAccEndpointConfigurationConfig_asyncNotifEmpty(rName string) string { + return acctest.ConfigCompose(testAccEndpointConfigurationConfig_base(rName), fmt.Sprintf(` +resource "aws_s3_bucket" "test" { + bucket = %[1]q + force_destroy = true +} + +resource "aws_sns_topic" "test" { + name = %[1]q +} + +resource "aws_kms_key" "test" { + description = %[1]q + deletion_window_in_days = 7 + enable_key_rotation = true +} + +resource "aws_sagemaker_endpoint_configuration" "test" { + name = %[1]q + + production_variants { + variant_name = "variant-1" + model_name = aws_sagemaker_model.test.name + initial_instance_count = 2 + instance_type = "ml.t2.medium" + initial_variant_weight = 1 + } + + async_inference_config { + output_config { + s3_output_path = "s3://${aws_s3_bucket.test.bucket}/" + kms_key_id = aws_kms_key.test.arn + + notification_config {} + } + } +} +`, rName)) +} + func testAccEndpointConfigurationConfig_asyncNotifInferenceIn(rName string) string { return acctest.ConfigCompose(testAccEndpointConfigurationConfig_base(rName), fmt.Sprintf(` resource "aws_s3_bucket" "test" { From 81910912914a2d611a13f754650ffe46dcc1de4e Mon Sep 17 00:00:00 2001 From: tabito Date: Tue, 16 Sep 2025 23:38:29 +0900 Subject: [PATCH 37/42] add changelog --- .changelog/44310.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/44310.txt diff --git a/.changelog/44310.txt b/.changelog/44310.txt new file mode 100644 index 000000000000..eb1f41bde34c --- /dev/null +++ b/.changelog/44310.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_sagemaker_endpoint_configuration: Fix panic when empty `async_inference_config.output_config.notification_config` block is specified +``` From 22b7ed9a97326b5c6cf489c4462b18681c738fe5 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 16 Sep 2025 11:19:37 -0400 Subject: [PATCH 38/42] d/aws_billing_views: adjust finders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ```console % make testacc PKG=billing TESTS=TestAccBillingViewsDataSource_ make: Verifying source code with gofmt... ==> Checking that code complies with gofmt requirements... make: Running acceptance tests on branch: 🌿 f-aws_billing_views-add_data_source 🌿... TF_ACC=1 go1.24.6 test ./internal/service/billing/... -v -count 1 -parallel 20 -run='TestAccBillingViewsDataSource_' -timeout 360m -vet=off 2025/09/16 11:17:52 Creating Terraform AWS Provider (SDKv2-style)... 2025/09/16 11:17:52 Initializing Terraform AWS Provider (SDKv2-style)... --- PASS: TestAccBillingViewsDataSource_basic (16.23s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/billing 22.894s ``` --- internal/service/billing/views_data_source.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/internal/service/billing/views_data_source.go b/internal/service/billing/views_data_source.go index c6763f2b3404..fdc4ebe17101 100644 --- a/internal/service/billing/views_data_source.go +++ b/internal/service/billing/views_data_source.go @@ -73,15 +73,18 @@ func (d *dataSourceViews) Read(ctx context.Context, req datasource.ReadRequest, } func findViewsByViewTypes(ctx context.Context, conn *billing.Client, billingViewTypes []awstypes.BillingViewType) ([]awstypes.BillingViewListElement, error) { - var results []awstypes.BillingViewListElement - input := billing.ListBillingViewsInput{} - if len(billingViewTypes) > 0 { input.BillingViewTypes = billingViewTypes } - paginator := billing.NewListBillingViewsPaginator(conn, &input) + return findViews(ctx, conn, &input) +} + +func findViews(ctx context.Context, conn *billing.Client, input *billing.ListBillingViewsInput) ([]awstypes.BillingViewListElement, error) { + var results []awstypes.BillingViewListElement + + paginator := billing.NewListBillingViewsPaginator(conn, input) for paginator.HasMorePages() { page, err := paginator.NextPage(ctx) if err != nil { @@ -89,6 +92,7 @@ func findViewsByViewTypes(ctx context.Context, conn *billing.Client, billingView } results = append(results, page.BillingViews...) } + return results, nil } From 19bf1ca146423cb3200b6adf9b2d162ef7a9a2db Mon Sep 17 00:00:00 2001 From: Justin Retzolk <44710313+justinretzolk@users.noreply.github.com> Date: Tue, 16 Sep 2025 10:37:00 -0500 Subject: [PATCH 39/42] Update skip_matching details for aws_autoscaling_group --- website/docs/r/autoscaling_group.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/autoscaling_group.html.markdown b/website/docs/r/autoscaling_group.html.markdown index bbe33e98dc50..e62672f5fcee 100644 --- a/website/docs/r/autoscaling_group.html.markdown +++ b/website/docs/r/autoscaling_group.html.markdown @@ -684,7 +684,7 @@ This configuration block supports the following: - `instance_warmup` - (Optional) Number of seconds until a newly launched instance is configured and ready to use. Default behavior is to use the Auto Scaling Group's health check grace period. - `max_healthy_percentage` - (Optional) Amount of capacity in the Auto Scaling group that can be in service and healthy, or pending, to support your workload when an instance refresh is in place, as a percentage of the desired capacity of the Auto Scaling group. Values must be between `100` and `200`, defaults to `100`. - `min_healthy_percentage` - (Optional) Amount of capacity in the Auto Scaling group that must remain healthy during an instance refresh to allow the operation to continue, as a percentage of the desired capacity of the Auto Scaling group. Defaults to `90`. - - `skip_matching` - (Optional) Replace instances that already have your desired configuration. Defaults to `false`. + - `skip_matching` - (Optional) Skip replacing instances that already have your desired configuration. Defaults to `false`. - `auto_rollback` - (Optional) Automatically rollback if instance refresh fails. Defaults to `false`. This option may only be set to `true` when specifying a `launch_template` or `mixed_instances_policy`. - `alarm_specification` - (Optional) Alarm Specification for Instance Refresh. - `alarms` - (Required) List of Cloudwatch alarms. If any of these alarms goes into ALARM state, Instance Refresh is failed. From de0fb51da5c9171a9da0740af24134cac624ba3c Mon Sep 17 00:00:00 2001 From: Asim Date: Tue, 16 Sep 2025 18:34:28 +0100 Subject: [PATCH 40/42] avmc added to service_package_gen.go --- internal/service/odb/service_package_gen.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/internal/service/odb/service_package_gen.go b/internal/service/odb/service_package_gen.go index 952fb1922304..ccb059cc69d8 100644 --- a/internal/service/odb/service_package_gen.go +++ b/internal/service/odb/service_package_gen.go @@ -19,6 +19,15 @@ type servicePackage struct{} func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*inttypes.ServicePackageFrameworkDataSource { return []*inttypes.ServicePackageFrameworkDataSource{ + { + Factory: newDataSourceCloudAutonomousVmCluster, + TypeName: "aws_odb_cloud_autonomous_vm_cluster", + Name: "Cloud Autonomous Vm Cluster", + Tags: unique.Make(inttypes.ServicePackageResourceTags{ + IdentifierAttribute: names.AttrARN, + }), + Region: unique.Make(inttypes.ResourceRegionDefault()), + }, { Factory: newDataSourceCloudExadataInfrastructure, TypeName: "aws_odb_cloud_exadata_infrastructure", @@ -42,6 +51,15 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*inttypes.S func (p *servicePackage) FrameworkResources(ctx context.Context) []*inttypes.ServicePackageFrameworkResource { return []*inttypes.ServicePackageFrameworkResource{ + { + Factory: newResourceCloudAutonomousVmCluster, + TypeName: "aws_odb_cloud_autonomous_vm_cluster", + Name: "Cloud Autonomous Vm Cluster", + Tags: unique.Make(inttypes.ServicePackageResourceTags{ + IdentifierAttribute: names.AttrARN, + }), + Region: unique.Make(inttypes.ResourceRegionDefault()), + }, { Factory: newResourceCloudExadataInfrastructure, TypeName: "aws_odb_cloud_exadata_infrastructure", From 53869180c832900328965c30a2ea3cd4ccf469a3 Mon Sep 17 00:00:00 2001 From: changelogbot Date: Tue, 16 Sep 2025 19:12:49 +0000 Subject: [PATCH 41/42] Update CHANGELOG.md for #44312 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42d12d2d1f62..a139bf06f178 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,10 @@ FEATURES: * **New Data Source:** `aws_odb_cloud_exadata_infrastructure` ([#43650](https://github.com/hashicorp/terraform-provider-aws/issues/43650)) +* **New Data Source:** `aws_odb_network` ([#43715](https://github.com/hashicorp/terraform-provider-aws/issues/43715)) * **New Resource:** `aws_controltower_baseline` ([#42397](https://github.com/hashicorp/terraform-provider-aws/issues/42397)) * **New Resource:** `aws_odb_cloud_exadata_infrastructure` ([#43650](https://github.com/hashicorp/terraform-provider-aws/issues/43650)) +* **New Resource:** `aws_odb_network` ([#43715](https://github.com/hashicorp/terraform-provider-aws/issues/43715)) ENHANCEMENTS: From f24bc0ea3d03b09c4625de6ae7f82ec480849e02 Mon Sep 17 00:00:00 2001 From: changelogbot Date: Wed, 17 Sep 2025 06:39:42 +0000 Subject: [PATCH 42/42] Update CHANGELOG.md for #44266 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a139bf06f178..e98b16f4ba17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,12 @@ FEATURES: +* **New Data Source:** `aws_billing_views` ([#44272](https://github.com/hashicorp/terraform-provider-aws/issues/44272)) +* **New Data Source:** `aws_odb_cloud_autonomous_vm_cluster` ([#43809](https://github.com/hashicorp/terraform-provider-aws/issues/43809)) * **New Data Source:** `aws_odb_cloud_exadata_infrastructure` ([#43650](https://github.com/hashicorp/terraform-provider-aws/issues/43650)) * **New Data Source:** `aws_odb_network` ([#43715](https://github.com/hashicorp/terraform-provider-aws/issues/43715)) * **New Resource:** `aws_controltower_baseline` ([#42397](https://github.com/hashicorp/terraform-provider-aws/issues/42397)) +* **New Resource:** `aws_odb_cloud_autonomous_vm_cluster` ([#43809](https://github.com/hashicorp/terraform-provider-aws/issues/43809)) * **New Resource:** `aws_odb_cloud_exadata_infrastructure` ([#43650](https://github.com/hashicorp/terraform-provider-aws/issues/43650)) * **New Resource:** `aws_odb_network` ([#43715](https://github.com/hashicorp/terraform-provider-aws/issues/43715)) @@ -13,6 +16,10 @@ ENHANCEMENTS: * resource/aws_rds_global_cluster: Remove provider-side conflict between `source_db_cluster_identifier` and `engine` arguments ([#44252](https://github.com/hashicorp/terraform-provider-aws/issues/44252)) * resource/aws_scheduler_schedule: Add `action_after_completion` argument ([#44264](https://github.com/hashicorp/terraform-provider-aws/issues/44264)) +BUG FIXES: + +* resource/aws_sagemaker_endpoint_configuration: Fix panic when empty `async_inference_config.output_config.notification_config` block is specified ([#44310](https://github.com/hashicorp/terraform-provider-aws/issues/44310)) + ## 6.13.0 (September 11, 2025) ENHANCEMENTS: