Skip to content

Commit

Permalink
Added isolation_segments datasource
Browse files Browse the repository at this point in the history
  • Loading branch information
Dray56 authored and debTheRay committed Nov 6, 2024
1 parent af605c9 commit f4b4255
Show file tree
Hide file tree
Showing 11 changed files with 778 additions and 1 deletion.
41 changes: 41 additions & 0 deletions docs/data-sources/isolation_segments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
page_title: "cloudfoundry_isolation_segments Data Source - terraform-provider-cloudfoundry"
subcategory: ""
description: |-
Gets information on Cloud Foundry Isolation Segments present.
---

# cloudfoundry_isolation_segments (Data Source)

Gets information on Cloud Foundry Isolation Segments present.

## Example Usage

```terraform
data "cloudfoundry_isolation_segments" "isosegments" {
name = "hifi"
}
```

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

### Optional

- `name` (String) Name of the isolation segment to filter by

### Read-Only

- `isolation_segments` (Attributes List) List of the isolation segments (see [below for nested schema](#nestedatt--isolation_segments))

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

Read-Only:

- `annotations` (Map of String) The annotations associated with Cloud Foundry resources.
- `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.
- `labels` (Map of String) The labels associated with Cloud Foundry resources.
- `name` (String) Name of the isolation segment
- `updated_at` (String) The date and time when the resource was updated in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "cloudfoundry_isolation_segments" "isosegments" {
name = "hifi"
}
118 changes: 118 additions & 0 deletions internal/provider/datasource_isolation_segments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
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"
"github.com/hashicorp/terraform-plugin-log/tflog"
)

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

func NewIsolationSegmentsDataSource() datasource.DataSource {
return &IsolationSegmentsDataSource{}
}

type IsolationSegmentsDataSource struct {
cfClient *cfv3client.Client
}

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

func (d *IsolationSegmentsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "Gets information on Cloud Foundry Isolation Segments present.",
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
MarkdownDescription: "Name of the isolation segment to filter by",
Optional: true,
},
"isolation_segments": schema.ListNestedAttribute{
MarkdownDescription: "List of the isolation segments",
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
idKey: guidSchema(),
"name": schema.StringAttribute{
MarkdownDescription: "Name of the isolation segment",
Computed: true,
},
labelsKey: datasourceLabelsSchema(),
annotationsKey: datasourceAnnotationsSchema(),
createdAtKey: createdAtSchema(),
updatedAtKey: updatedAtSchema(),
},
},
},
},
}
}

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

var data IsolationSegmentsType

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

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

isolationSegments, err := d.cfClient.IsolationSegments.ListAll(ctx, getOptions)
if err != nil {
resp.Diagnostics.AddError(
"API Error Fetching Isolation Segment.",
fmt.Sprintf("Request failed with %s.", err.Error()),
)
return
}

if len(isolationSegments) == 0 {
resp.Diagnostics.AddError(
"Unable to find any Isolation Segment in given list",
"No isolation segment found with given criteria",
)
return
}

data.IsolationSegments, diags = mapIsolationSegmentsValuesToType(ctx, isolationSegments)
resp.Diagnostics.Append(diags...)

tflog.Trace(ctx, "read an isolation segments data source")
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
93 changes: 93 additions & 0 deletions internal/provider/datasource_isolation_segments_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package provider

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

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

type IsolationSegmentsModelPtr struct {
HclType string
HclObjectName string
Name *string
IsolationSegments *string
}

func hclIsolationSegments(ismp *IsolationSegmentsModelPtr) string {
if ismp != nil {
s := `
{{.HclType}} "cloudfoundry_isolation_segments" "{{.HclObjectName}}" {
{{- if .Name}}
name = "{{.Name}}"
{{- end -}}
{{if .IsolationSegments}}
isolation_segments = {{.IsolationSegments}}
{{- end }}
}`
tmpl, err := template.New("isolation_segments").Parse(s)
if err != nil {
panic(err)
}
buf := new(bytes.Buffer)
err = tmpl.Execute(buf, ismp)
if err != nil {
panic(err)
}
return buf.String()
}
return ismp.HclType + ` cloudfoundry_isolation_segments" ` + ismp.HclObjectName + ` {}`
}

func TestIsolationSegmentsDataSource_Configure(t *testing.T) {
var (
// in staging
isolationSegmentName = "trial"
resourceName = "data.cloudfoundry_isolation_segments.ds"
)
t.Parallel()
t.Run("get available datasource isolation segments", func(t *testing.T) {
cfg := getCFHomeConf()
rec := cfg.SetupVCR(t, "fixtures/datasource_isolation_segments")
defer stopQuietly(rec)

resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: getProviders(rec.GetDefaultClient()),
Steps: []resource.TestStep{
{
Config: hclProvider(nil) + hclIsolationSegments(&IsolationSegmentsModelPtr{
HclType: hclObjectDataSource,
HclObjectName: "ds",
Name: &isolationSegmentName,
}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "isolation_segments.#", "1"),
),
},
},
})
})
t.Run("error path - get unavailable isolation segments", func(t *testing.T) {
cfg := getCFHomeConf()
rec := cfg.SetupVCR(t, "fixtures/datasource_isolation_segments_invalid")
defer stopQuietly(rec)

resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: getProviders(rec.GetDefaultClient()),
Steps: []resource.TestStep{
{
Config: hclProvider(nil) + hclIsolationSegments(&IsolationSegmentsModelPtr{
HclType: hclObjectDataSource,
HclObjectName: "ds",
Name: strtostrptr("testunavailable"),
}),
ExpectError: regexp.MustCompile(`Unable to find any Isolation Segment in given list`),
},
},
})
})
}
Loading

0 comments on commit f4b4255

Please sign in to comment.