Skip to content

Commit

Permalink
Added service_route_bindings datasource (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dray56 authored Nov 5, 2024
1 parent d1cbbb6 commit 9843704
Show file tree
Hide file tree
Showing 10 changed files with 844 additions and 0 deletions.
63 changes: 63 additions & 0 deletions docs/data-sources/service_route_bindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
page_title: "cloudfoundry_service_route_bindings Data Source - terraform-provider-cloudfoundry"
subcategory: ""
description: |-
Gets information on Service Route Bindings the user has access to.
---

# cloudfoundry_service_route_bindings (Data Source)

Gets information on Service Route Bindings the user has access to.

## Example Usage

```terraform
data "cloudfoundry_service_route_bindings" "rbs" {
service_instance = "ab65cad9-73fa-4dd4-9c09-87f89b2e77ec"
}
output "bindings" {
value = data.cloudfoundry_service_route_bindings.rbs
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Optional

- `route` (String) The GUID of the route to filter by
- `service_instance` (String) The GUID of the service instance to filter by

### Read-Only

- `route_bindings` (Attributes List) The list of route bindings for the given service instance. (see [below for nested schema](#nestedatt--route_bindings))

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

Optional:

- `annotations` (Map of String) The annotations associated with Cloud Foundry resources. Add as described [here](https://docs.cloudfoundry.org/adminguide/metadata.html#-view-metadata-for-an-object).
- `labels` (Map of String) The labels associated with Cloud Foundry resources. Add as described [here](https://docs.cloudfoundry.org/adminguide/metadata.html#-view-metadata-for-an-object).

Read-Only:

- `created_at` (String) The date and time when the resource was created in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format.
- `id` (String) The GUID of the object.
- `last_operation` (Attributes) The details of the last operation performed on the resource (see [below for nested schema](#nestedatt--route_bindings--last_operation))
- `route` (String) The GUID of the route to be bound
- `route_service_url` (String) The URL for the route service.
- `service_instance` (String) The service instance that the route is bound to
- `updated_at` (String) The date and time when the resource was updated in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format.

<a id="nestedatt--route_bindings--last_operation"></a>
### Nested Schema for `route_bindings.last_operation`

Read-Only:

- `created_at` (String) The time at which the last operation was created
- `description` (String) A description of the last operation
- `state` (String) The state of the last operation
- `type` (String) The type of the last operation
- `updated_at` (String) The time at which the last operation was updated
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
data "cloudfoundry_service_route_bindings" "rbs" {
service_instance = "ab65cad9-73fa-4dd4-9c09-87f89b2e77ec"
}

output "bindings" {
value = data.cloudfoundry_service_route_bindings.rbs
}
138 changes: 138 additions & 0 deletions internal/provider/datasource_service_route_bindings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package provider

import (
"context"
"fmt"

cfv3client "github.com/cloudfoundry/go-cfclient/v3/client"
"github.com/cloudfoundry/terraform-provider-cloudfoundry/internal/provider/managers"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
)

// Ensure provider defined types fully satisfy framework interfaces.
var (
_ datasource.DataSource = &ServiceRouteBindingsDataSource{}
_ datasource.DataSourceWithConfigure = &ServiceRouteBindingsDataSource{}
)

func NewServiceRouteBindingsDataSource() datasource.DataSource {
return &ServiceRouteBindingsDataSource{}
}

type ServiceRouteBindingsDataSource struct {
cfClient *cfv3client.Client
}

func (d *ServiceRouteBindingsDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_service_route_bindings"
}

func (d *ServiceRouteBindingsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "Gets information on Service Route Bindings the user has access to.",

Attributes: map[string]schema.Attribute{
"service_instance": schema.StringAttribute{
MarkdownDescription: "The GUID of the service instance to filter by",
Optional: true,
},
"route": schema.StringAttribute{
MarkdownDescription: "The GUID of the route to filter by",
Optional: true,
},
"route_bindings": schema.ListNestedAttribute{
MarkdownDescription: "The list of route bindings for the given service instance.",
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"service_instance": schema.StringAttribute{
MarkdownDescription: "The service instance that the route is bound to",
Computed: true,
},
"route": schema.StringAttribute{
MarkdownDescription: "The GUID of the route to be bound",
Computed: true,
},
"route_service_url": schema.StringAttribute{
MarkdownDescription: "The URL for the route service.",
Computed: true,
},
"last_operation": lastOperationSchema(),
idKey: guidSchema(),
labelsKey: resourceLabelsSchema(),
annotationsKey: resourceAnnotationsSchema(),
createdAtKey: createdAtSchema(),
updatedAtKey: updatedAtSchema(),
},
},
},
},
}
}

func (d *ServiceRouteBindingsDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}
session, ok := req.ProviderData.(*managers.Session)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *managers.Session, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)
return
}
d.cfClient = session.CFClient
}

func (d *ServiceRouteBindingsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {

var data datasourceserviceRouteBindingsType

diags := req.Config.Get(ctx, &data)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

getOptions := cfv3client.NewServiceRouteBindingListOptions()

if !data.ServiceInstance.IsNull() {
getOptions.ServiceInstanceGUIDs = cfv3client.Filter{
Values: []string{
data.ServiceInstance.ValueString(),
},
}
}

if !data.Route.IsNull() {
getOptions.RouteGUIDs = cfv3client.Filter{
Values: []string{
data.Route.ValueString(),
},
}
}

svcRouteBindings, err := d.cfClient.ServiceRouteBindings.ListAll(ctx, getOptions)
if err != nil {
resp.Diagnostics.AddError(
"API Error Fetching Service Route Bindings.",
fmt.Sprintf("Request failed with %s.", err.Error()),
)
return
}

if len(svcRouteBindings) == 0 {
resp.Diagnostics.AddError(
"Unable to find any route bindings in list",
"Given input does not have any bindings present",
)
return
}

data.RouteBindings, diags = mapDataSourceServiceRouteBindingsValuesToType(ctx, svcRouteBindings)
resp.Diagnostics.Append(diags...)
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
94 changes: 94 additions & 0 deletions internal/provider/datasource_service_route_bindings_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package provider

import (
"bytes"
"regexp"
"testing"
"text/template"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

type ServiceRouteBindingsModelPtr struct {
HclType string
HclObjectName string
Route *string
Routes *string
ServiceInstance *string
}

func hclServiceRouteBindings(sip *ServiceRouteBindingsModelPtr) string {
if sip != nil {
s := `
{{.HclType}} "cloudfoundry_service_route_bindings" {{.HclObjectName}} {
{{- if .Route}}
route = "{{.Route}}"
{{- end -}}
{{if .ServiceInstance}}
service_instance = "{{.ServiceInstance}}"
{{- end }}
{{if .Routes}}
routes = "{{.Routes}}"
{{- end }}
}`
tmpl, err := template.New("service_route_bindings").Parse(s)
if err != nil {
panic(err)
}
buf := new(bytes.Buffer)
err = tmpl.Execute(buf, sip)
if err != nil {
panic(err)
}
return buf.String()
}
return sip.HclType + ` "cloudfoundry_service_route_bindings" "` + sip.HclObjectName + ` {}`
}

func TestServiceRouteBindingsDataSource(t *testing.T) {
var (
ServiceInstanceGUID = "ab65cad9-73fa-4dd4-9c09-87f89b2e77ec"
)
t.Parallel()
t.Run("happy path - read route bindings", func(t *testing.T) {
cfg := getCFHomeConf()
dataSourceName := "data.cloudfoundry_service_route_bindings.ds"
rec := cfg.SetupVCR(t, "fixtures/datasource_service_route_bindings")
defer stopQuietly(rec)
resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: getProviders(rec.GetDefaultClient()),
Steps: []resource.TestStep{
{
Config: hclProvider(nil) + hclServiceRouteBindings(&ServiceRouteBindingsModelPtr{
HclType: hclObjectDataSource,
HclObjectName: "ds",
ServiceInstance: &ServiceInstanceGUID,
}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "route_bindings.#", "1"),
),
},
},
})
})
t.Run("error path - get unavailable route bindings", func(t *testing.T) {
cfg := getCFHomeConf()
rec := cfg.SetupVCR(t, "fixtures/datasource_service_route_bindings_invalid")
defer stopQuietly(rec)
resource.UnitTest(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: getProviders(rec.GetDefaultClient()),
Steps: []resource.TestStep{
{
Config: hclProvider(nil) + hclServiceRouteBindings(&ServiceRouteBindingsModelPtr{
HclType: hclObjectDataSource,
HclObjectName: "ds",
Route: &ServiceInstanceGUID,
}),
ExpectError: regexp.MustCompile(`Unable to find any route bindings in list`),
},
},
})
})
}
Loading

0 comments on commit 9843704

Please sign in to comment.