Skip to content

Commit

Permalink
Added service brokers datasource (#62)
Browse files Browse the repository at this point in the history
Signed-off-by: Ray <[email protected]>
  • Loading branch information
Dray56 authored Nov 5, 2024
1 parent 9843704 commit a52f7ab
Show file tree
Hide file tree
Showing 10 changed files with 1,188 additions and 2 deletions.
54 changes: 54 additions & 0 deletions docs/data-sources/service_brokers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
page_title: "cloudfoundry_service_brokers Data Source - terraform-provider-cloudfoundry"
subcategory: ""
description: |-
Gets information of Service brokers user has access to.
---

# cloudfoundry_service_brokers (Data Source)

Gets information of Service brokers user has access to.

## Example Usage

```terraform
data "cloudfoundry_service_brokers" "brokers" {
space = "02c0cc92-6ecc-44b1-b7b2-096ca19ee143"
}
output "se_brs" {
value = data.cloudfoundry_service_brokers.brokers
}
```

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

### Optional

- `name` (String) Name of the service broker to filter by
- `space` (String) GUID of the space to filter by

### Read-Only

- `service_brokers` (Attributes List) List of service brokers (see [below for nested schema](#nestedatt--service_brokers))

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

Required:

- `name` (String) Name of the service broker

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.
- `space` (String) The GUID of the space the service broker is restricted to; omitted for globally available service brokers
- `updated_at` (String) The date and time when the resource was updated in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format.
- `url` (String) URL of the service broker
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
data "cloudfoundry_service_brokers" "brokers" {
space = "02c0cc92-6ecc-44b1-b7b2-096ca19ee143"
}

output "se_brs" {
value = data.cloudfoundry_service_brokers.brokers
}
126 changes: 126 additions & 0 deletions internal/provider/datasource_service_brokers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
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"
)

func NewServiceBrokersDataSource() datasource.DataSource {
return &ServiceBrokersDataSource{}
}

type ServiceBrokersDataSource struct {
cfClient *cfv3client.Client
}

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

func (d *ServiceBrokersDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "Gets information of Service brokers user has access to.",
Attributes: map[string]schema.Attribute{
"space": schema.StringAttribute{
MarkdownDescription: "GUID of the space to filter by",
Optional: true,
},
"name": schema.StringAttribute{
MarkdownDescription: "Name of the service broker to filter by",
Optional: true,
},
"service_brokers": schema.ListNestedAttribute{
MarkdownDescription: "List of service brokers",
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
MarkdownDescription: "Name of the service broker",
Required: true,
},
"url": schema.StringAttribute{
MarkdownDescription: "URL of the service broker",
Computed: true,
},
"space": schema.StringAttribute{
MarkdownDescription: "The GUID of the space the service broker is restricted to; omitted for globally available service brokers",
Computed: true,
},
idKey: guidSchema(),
labelsKey: resourceLabelsSchema(),
annotationsKey: resourceAnnotationsSchema(),
createdAtKey: createdAtSchema(),
updatedAtKey: updatedAtSchema(),
},
},
},
},
}
}

func (d *ServiceBrokersDataSource) 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 *ServiceBrokersDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {

var data datasourceServiceBrokersType

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

getOptions := cfv3client.NewServiceBrokerListOptions()
if !data.Name.IsNull() {
getOptions.Names = cfv3client.Filter{
Values: []string{
data.Name.ValueString(),
},
}
}
if !data.Space.IsNull() {
getOptions.SpaceGUIDs = cfv3client.Filter{
Values: []string{
data.Space.ValueString(),
},
}
}
svcBrokers, err := d.cfClient.ServiceBrokers.ListAll(ctx, getOptions)
if err != nil {
resp.Diagnostics.AddError(
"API Error in fetching service broker data.",
fmt.Sprintf("Request failed with %s.", err.Error()),
)
return
}
if len(svcBrokers) == 0 {
resp.Diagnostics.AddError(
"Unable to find any service broker in list",
"No service brokers present with mentioned criteria",
)
return
}

data.ServiceBrokers, diags = mapDataSourceServiceBrokersValuesToType(ctx, svcBrokers)
resp.Diagnostics.Append(diags...)
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
102 changes: 102 additions & 0 deletions internal/provider/datasource_service_brokers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package provider

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

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

type ServiceBrokersModelPtr struct {
HclType string
HclObjectName string
Name *string
Space *string
ServiceBrokers *string
}

func hclServiceBrokers(sbmp *ServiceBrokersModelPtr) string {
if sbmp != nil {
s := `
{{.HclType}} "cloudfoundry_service_brokers" {{.HclObjectName}} {
{{- if .Name}}
name = "{{.Name}}"
{{- end -}}
{{if .Space}}
space = "{{.Space}}"
{{- end -}}
{{if .ServiceBrokers}}
service_brokers = "{{.ServiceBrokers}}"
{{- end }}
}`
tmpl, err := template.New("datasource_service_brokers").Parse(s)
if err != nil {
panic(err)
}
buf := new(bytes.Buffer)
err = tmpl.Execute(buf, sbmp)
if err != nil {
panic(err)
}
return buf.String()
}
return sbmp.HclType + ` "cloudfoundry_service_brokers" ` + sbmp.HclObjectName + ` {}`
}

func TestServiceBrokersDataSource(t *testing.T) {
t.Parallel()
t.Run("happy path - read service brokers", func(t *testing.T) {
cfg := getCFHomeConf()
dataSourceName := "data.cloudfoundry_service_brokers.ds"
rec := cfg.SetupVCR(t, "fixtures/datasource_service_brokers")
defer stopQuietly(rec)
resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: getProviders(rec.GetDefaultClient()),
Steps: []resource.TestStep{
{
Config: hclProvider(nil) + hclServiceBrokers(&ServiceBrokersModelPtr{
HclType: hclObjectDataSource,
HclObjectName: "ds",
}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "service_brokers.#", "3"),
),
},
{
Config: hclProvider(nil) + hclServiceBrokers(&ServiceBrokersModelPtr{
HclType: hclObjectDataSource,
HclObjectName: "ds",
Name: strtostrptr("hi"),
}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "service_brokers.#", "1"),
),
},
},
})
})
t.Run("error path - get unavailable service brokers", func(t *testing.T) {
cfg := getCFHomeConf()
rec := cfg.SetupVCR(t, "fixtures/datasource_service_brokers_invalid")
defer stopQuietly(rec)
// Create a Terraform configuration that uses the data source
// and run `terraform apply`. The data source should not be found.
resource.UnitTest(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: getProviders(rec.GetDefaultClient()),
Steps: []resource.TestStep{
{
Config: hclProvider(nil) + hclServiceBrokers(&ServiceBrokersModelPtr{
HclType: hclObjectDataSource,
HclObjectName: "ds",
Name: strtostrptr("invalid-service-broker-name"),
}),
ExpectError: regexp.MustCompile(`Unable to find any service broker in list`),
},
},
})
})
}
Loading

0 comments on commit a52f7ab

Please sign in to comment.