Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added service brokers datasource #62

Merged
merged 1 commit into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading