Skip to content

Commit

Permalink
provider: add services map to private_endpoint_services
Browse files Browse the repository at this point in the history
Previously, the private_endpoint_services resource contains the regional
services in a list. This made it hard for users to access the service
for a given region. This commit adds a service map that contains all the
services but are keyed by the cloud region.
  • Loading branch information
carloruiz committed Jun 19, 2024
1 parent 052f11c commit 8a18746
Show file tree
Hide file tree
Showing 12 changed files with 334 additions and 52 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Enable log export for serverless clusters.

- Add services_map to private_endpoint_services resource.

## [1.7.6] - 2024-06-10

## Fixed
Expand Down
25 changes: 25 additions & 0 deletions docs/resources/private_endpoint_services.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ resource "cockroach_private_endpoint_services" "cockroach" {

- `id` (String) Always matches the cluster ID. Required by Terraform.
- `services` (Attributes List) (see [below for nested schema](#nestedatt--services))
- `services_map` (Attributes Map) a map of services keyed by the region name (see [below for nested schema](#nestedatt--services_map))

<a id="nestedatt--services"></a>
### Nested Schema for `services`
Expand All @@ -56,6 +57,30 @@ Read-Only:
- `service_id` (String) Server side ID of the PrivateLink connection.
- `service_name` (String) AWS service name used to create endpoints.



<a id="nestedatt--services_map"></a>
### Nested Schema for `services_map`

Read-Only:

- `availability_zone_ids` (List of String) 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` (Attributes, Deprecated) (see [below for nested schema](#nestedatt--services_map--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.

<a id="nestedatt--services_map--aws"></a>
### Nested Schema for `services_map.aws`

Read-Only:

- `availability_zone_ids` (List of String) AZ IDs users should create their VPCs in to minimize their cost.
- `service_id` (String) Server side ID of the PrivateLink connection.
- `service_name` (String) AWS service name used to create endpoints.

## Import

Import is supported using the following syntax:
Expand Down
7 changes: 4 additions & 3 deletions internal/provider/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,10 @@ type PrivateEndpointService struct {
}

type PrivateEndpointServices struct {
ClusterID types.String `tfsdk:"cluster_id"`
Services types.List `tfsdk:"services"`
ID types.String `tfsdk:"id"`
ClusterID types.String `tfsdk:"cluster_id"`
Services types.List `tfsdk:"services"`
ServicesMap types.Map `tfsdk:"services_map"`
ID types.String `tfsdk:"id"`
}

type PrivateEndpointConnection struct {
Expand Down
124 changes: 75 additions & 49 deletions internal/provider/private_endpoint_services_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/mapplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
Expand Down Expand Up @@ -57,60 +58,70 @@ var endpointServicesSchema = schema.Schema{
},
MarkdownDescription: "Always matches the cluster ID. Required by Terraform.",
},
"services_map": schema.MapNestedAttribute{
Computed: true,
Description: "a map of services keyed by the region name",
PlanModifiers: []planmodifier.Map{
mapplanmodifier.UseStateForUnknown(),
},
NestedObject: serviceObject,
},
"services": schema.ListNestedAttribute{
Computed: true,
PlanModifiers: []planmodifier.List{
listplanmodifier.UseStateForUnknown(),
},
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"region_name": schema.StringAttribute{
Computed: true,
Description: "Cloud provider region code associated with this service.",
},
"cloud_provider": schema.StringAttribute{
Computed: true,
Description: "Cloud provider associated with this service.",
},
"status": schema.StringAttribute{
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{
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(),
},
Attributes: map[string]schema.Attribute{
"service_name": schema.StringAttribute{
Computed: true,
Description: "AWS service name used to create endpoints.",
},
"service_id": schema.StringAttribute{
Computed: true,
Description: "Server side ID of the PrivateLink connection.",
},
"availability_zone_ids": schema.ListAttribute{
Computed: true,
ElementType: types.StringType,
MarkdownDescription: "AZ IDs users should create their VPCs in to minimize their cost.",
},
},
},
NestedObject: serviceObject,
},
},
}

var serviceObject = schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"region_name": schema.StringAttribute{
Computed: true,
Description: "Cloud provider region code associated with this service.",
},
"cloud_provider": schema.StringAttribute{
Computed: true,
Description: "Cloud provider associated with this service.",
},
"status": schema.StringAttribute{
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{
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(),
},
Attributes: map[string]schema.Attribute{
"service_name": schema.StringAttribute{
Computed: true,
Description: "AWS service name used to create endpoints.",
},
"service_id": schema.StringAttribute{
Computed: true,
Description: "Server side ID of the PrivateLink connection.",
},
"availability_zone_ids": schema.ListAttribute{
Computed: true,
ElementType: types.StringType,
MarkdownDescription: "AZ IDs users should create their VPCs in to minimize their cost.",
},
},
},
Expand Down Expand Up @@ -277,6 +288,21 @@ func loadEndpointServicesIntoTerraformState(
endpointServicesSchema.Attributes["services"].(schema.ListNestedAttribute).NestedObject.Type(),
services,
)

servicesMap := map[string]PrivateEndpointService{}
for _, svc := range services {
servicesMap[svc.RegionName.ValueString()] = svc
}

var diags2 diag.Diagnostics
state.ServicesMap, diags2 = types.MapValueFrom(
ctx,
endpointServicesSchema.Attributes["services_map"].(schema.MapNestedAttribute).NestedObject.Type(),
servicesMap,
)

diags.Append(diags2...)

return diags
}

Expand Down
5 changes: 5 additions & 0 deletions internal/provider/private_endpoint_services_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,18 @@ func testPrivateEndpointServicesResource(
checks := []resource.TestCheckFunc{
resource.TestCheckResourceAttr(clusterResourceName, "name", clusterName),
resource.TestCheckResourceAttr(resourceName, "services.#", strconv.Itoa(numExpectedServices)),
resource.TestCheckResourceAttr(resourceName, "services_map.%", strconv.Itoa(numExpectedServices)),
}
for i := 0; i < numExpectedServices; i++ {
svc := fmt.Sprintf("services.%d", i)
checks = append(checks,
resource.TestCheckResourceAttr(resourceName, svc+".status", string(client.PRIVATEENDPOINTSERVICESTATUSTYPE_AVAILABLE)),
)

checks = append(checks,
resource.TestCheckResourceAttrPair(resourceName, svc, resourceName, "services_map.us-east-1"),
)

if cloud == client.CLOUDPROVIDERTYPE_AWS {
checks = append(checks, []resource.TestCheckFunc{
resource.TestCheckResourceAttrPair(resourceName, svc+".name", resourceName, svc+".aws.service_name"),
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8a18746

Please sign in to comment.