diff --git a/CHANGELOG.md b/CHANGELOG.md index 48f8935b..f6b1ec49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Changed - -- Migrated the testing framework to - https://github.com/hashicorp/terraform-plugin-testing. - -## [1.3.2] - 2024-03-13 +## [1.3.2] - 2024-03-15 ### Changed @@ -21,8 +16,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 except Serverless clusters on Azure as that configuration is not yet available. +- Migrated the testing framework to + https://github.com/hashicorp/terraform-plugin-testing. + +- The `private_endpoint_services` resource can now be used to create private + endpoint services on every supported cloud provider. + +- Use CockroachDB v23.1 and v23.2 in tests. + ### Fixed +- The `private_endpoint_services` resource could be created without populating + the state file with the service information. + - Renamed example files to the correct name so they are automatically included in the docs. diff --git a/docs/resources/private_endpoint_services.md b/docs/resources/private_endpoint_services.md index 886d4259..44b71a6e 100644 --- a/docs/resources/private_endpoint_services.md +++ b/docs/resources/private_endpoint_services.md @@ -3,12 +3,12 @@ page_title: "cockroach_private_endpoint_services Resource - terraform-provider-cockroach" subcategory: "" description: |- - PrivateEndpointServices contains services that allow for VPC communication, either via PrivateLink (AWS) or Peering (GCP). + PrivateEndpointServices contains services that allow for for private connectivity to the CockroachDB Cloud cluster. --- # cockroach_private_endpoint_services (Resource) -PrivateEndpointServices contains services that allow for VPC communication, either via PrivateLink (AWS) or Peering (GCP). +PrivateEndpointServices contains services that allow for for private connectivity to the CockroachDB Cloud cluster. ## Example Usage @@ -39,8 +39,11 @@ resource "cockroach_private_endpoint_services" "cockroach" { Read-Only: -- `aws` (Attributes) (see [below for nested schema](#nestedatt--services--aws)) +- `availability_zone_ids` (List of String) AZ IDs users should create their VPCs in to minimize their cost. +- `aws` (Attributes, Deprecated) (see [below for nested schema](#nestedatt--services--aws)) - `cloud_provider` (String) Cloud provider associated with this service. +- `endpoint_service_id` (String) Server side ID of the private endpoint connection. +- `name` (String) Name of the endpoint service. - `region_name` (String) Cloud provider region code associated with this service. - `status` (String) Operation status of the service. diff --git a/internal/provider/cluster_resource_test.go b/internal/provider/cluster_resource_test.go index 9f9b3836..6923a9c4 100644 --- a/internal/provider/cluster_resource_test.go +++ b/internal/provider/cluster_resource_test.go @@ -40,10 +40,10 @@ const ( // The patch versions are just for mocks. They don't need to be the actual // latest available patch versions; they just need to resolve to the correct // major versions. - minSupportedClusterMajorVersion = "v22.2" - minSupportedClusterPatchVersion = "v22.2.0" - latestClusterMajorVersion = "v23.1" - latestClusterPatchVersion = "v23.1.0" + minSupportedClusterMajorVersion = "v23.1" + minSupportedClusterPatchVersion = "v23.1.0" + latestClusterMajorVersion = "v23.2" + latestClusterPatchVersion = "v23.2.0" ) // TestAccClusterResource attempts to create, check, update, and destroy diff --git a/internal/provider/models.go b/internal/provider/models.go index f3dd23f4..15706d3f 100644 --- a/internal/provider/models.go +++ b/internal/provider/models.go @@ -107,10 +107,13 @@ type PrivateLinkServiceAWSDetail struct { } type PrivateEndpointService struct { - RegionName types.String `tfsdk:"region_name"` - CloudProvider types.String `tfsdk:"cloud_provider"` - Status types.String `tfsdk:"status"` - Aws PrivateLinkServiceAWSDetail `tfsdk:"aws"` + RegionName types.String `tfsdk:"region_name"` + CloudProvider types.String `tfsdk:"cloud_provider"` + Status types.String `tfsdk:"status"` + Name types.String `tfsdk:"name"` + EndpointServiceId types.String `tfsdk:"endpoint_service_id"` + AvailabilityZoneIds []types.String `tfsdk:"availability_zone_ids"` + Aws PrivateLinkServiceAWSDetail `tfsdk:"aws"` } type PrivateEndpointServices struct { diff --git a/internal/provider/private_endpoint_services_resource.go b/internal/provider/private_endpoint_services_resource.go index 2a472457..12c81760 100644 --- a/internal/provider/private_endpoint_services_resource.go +++ b/internal/provider/private_endpoint_services_resource.go @@ -42,7 +42,7 @@ type privateEndpointServicesResource struct { const endpointServicesCreateTimeout = time.Hour var endpointServicesSchema = schema.Schema{ - MarkdownDescription: "PrivateEndpointServices contains services that allow for VPC communication, either via PrivateLink (AWS) or Peering (GCP).", + MarkdownDescription: "PrivateEndpointServices contains services that allow for private connectivity to the CockroachDB Cloud cluster.", Attributes: map[string]schema.Attribute{ "cluster_id": schema.StringAttribute{ Required: true, @@ -76,8 +76,22 @@ var endpointServicesSchema = schema.Schema{ Computed: true, Description: "Operation status of the service.", }, + "name": schema.StringAttribute{ + Computed: true, + Description: "Name of the endpoint service.", + }, + "endpoint_service_id": schema.StringAttribute{ + Computed: true, + Description: "Server side ID of the private endpoint connection.", + }, + "availability_zone_ids": schema.ListAttribute{ + Computed: true, + ElementType: types.StringType, + MarkdownDescription: "Availability Zone IDs of the private endpoint service. It is recommended, for cost optimization purposes, to create the private endpoint spanning these same availability zones. For more information, see data transfer cost information for your cloud provider.", + }, "aws": schema.SingleNestedAttribute{ - Computed: true, + DeprecationMessage: "nested aws fields have been moved one level up. These fields will be removed in a future version", + Computed: true, PlanModifiers: []planmodifier.Object{ objectplanmodifier.UseStateForUnknown(), }, @@ -152,14 +166,6 @@ func (r *privateEndpointServicesResource) Create( return } - if cluster.CloudProvider != client.CLOUDPROVIDERTYPE_AWS { - resp.Diagnostics.AddError( - "Incompatible cluster cloud provider", - "Private endpoint services are currently only available for AWS clusters", - ) - return - } - // Only create an endpoint service if it is a dedicated cluster. Serverless // clusters have endpoint services by default, and will error out if the // Create API is called. @@ -236,19 +242,26 @@ func loadEndpointServicesIntoTerraformState( services := make([]PrivateEndpointService, len(serviceList)) for i, service := range serviceList { services[i] = PrivateEndpointService{ - RegionName: types.StringValue(service.GetRegionName()), - CloudProvider: types.StringValue(string(service.GetCloudProvider())), - Status: types.StringValue(string(service.GetStatus())), - Aws: PrivateLinkServiceAWSDetail{ + RegionName: types.StringValue(service.GetRegionName()), + CloudProvider: types.StringValue(string(service.GetCloudProvider())), + Status: types.StringValue(string(service.GetStatus())), + Name: types.StringValue(service.GetName()), + EndpointServiceId: types.StringValue(service.GetEndpointServiceId()), + } + + if services[i].CloudProvider.String() == "AWS" { + services[i].Aws = PrivateLinkServiceAWSDetail{ ServiceName: types.StringValue(service.Aws.GetServiceName()), ServiceId: types.StringValue(service.Aws.GetServiceId()), - }, + } } - apiAZs := service.Aws.GetAvailabilityZoneIds() + + apiAZs := service.GetAvailabilityZoneIds() azs := make([]types.String, len(apiAZs)) for j, az := range apiAZs { azs[j] = types.StringValue(az) } + services[i].AvailabilityZoneIds = azs services[i].Aws.AvailabilityZoneIds = azs } var diags diag.Diagnostics @@ -299,9 +312,14 @@ func waitForEndpointServicesCreatedFunc( if httpResp != nil && httpResp.StatusCode < http.StatusInternalServerError { return retry.NonRetryableError(fmt.Errorf("error getting endpoint services: %s", formatAPIErrorMessage(err))) } else { - return retry.RetryableError(fmt.Errorf("encountered a server error while reading endpoint status - trying again")) + return retry.RetryableError(fmt.Errorf("encountered a server error while reading endpoint status - trying again: %v", err)) } } + + if len(apiServices.Services) == 0 { + return retry.RetryableError(fmt.Errorf("private endpoint services not yet created")) + } + *services = *apiServices var creating bool // If there's at least one still creating, keep checking.