Skip to content

Commit

Permalink
Merge pull request #3 from omc/feat/add-release-data-source
Browse files Browse the repository at this point in the history
Add bonsai_release (GetBySlug) and bonsai_releases (List) data sources.
  • Loading branch information
momer authored May 14, 2024
2 parents 77bb1eb + 6041108 commit 3a13e2a
Show file tree
Hide file tree
Showing 14 changed files with 423 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ repos:
name: task-docs
description: Run the docs task for documentation generation
entry: task docs
types: [ go ]
types_or: [ go, terraform, markdown ]
language: system
require_serial: true
pass_filenames: false
2 changes: 1 addition & 1 deletion .task/checksum/docs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f7f04e4db1b11ccfe67e14765ab91cb3
759ba68929e54e055e8873c1a30cef6a
33 changes: 33 additions & 0 deletions docs/data-sources/release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "bonsai_release Data Source - terraform-provider-bonsai"
subcategory: ""
description: |-
A Release is a version of Elasticsearch available to your account.
---

# bonsai_release (Data Source)

A Release is a version of Elasticsearch available to your account.

## Example Usage

```terraform
data "bonsai_release" "get_by_slug" {
slug = "elasticsearch-6.4.2"
}
```

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

### Optional

- `slug` (String) The machine-readable name for the deployment.

### Read-Only

- `multitenant` (Boolean) Whether the release is available on multitenant deployments.
- `name` (String) The name for the release.
- `service_type` (String) The service type of the deployment - for example, "elasticsearch".
- `version` (String) The version of the release.
38 changes: 38 additions & 0 deletions docs/data-sources/releases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "bonsai_releases Data Source - terraform-provider-bonsai"
subcategory: ""
description: |-
A list of all available releases on your account.
---

# bonsai_releases (Data Source)

A list of all **available** releases on your account.

## Example Usage

```terraform
data "bonsai_releases" "list" {}
```

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

### Read-Only

- `releases` (Attributes List) A Release is a version of Elasticsearch available to your account. (see [below for nested schema](#nestedatt--releases))

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

Optional:

- `slug` (String) The machine-readable name for the deployment.

Read-Only:

- `multitenant` (Boolean) Whether the release is available on multitenant deployments.
- `name` (String) The name for the release.
- `service_type` (String) The service type of the deployment - for example, "elasticsearch".
- `version` (String) The version of the release.
16 changes: 16 additions & 0 deletions examples/complete/complete.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ terraform {
}
}

// Bonsai Spaces
provider "bonsai" {}

data "bonsai_space" "get_by_path" {
Expand All @@ -21,3 +22,18 @@ output "bonsai_space" {
output "bonsai_spaces" {
value = data.bonsai_spaces.list
}

// Bonsai Releases
data "bonsai_release" "get_by_slug" {
slug = "elasticsearch-6.4.2"
}

data "bonsai_releases" "list" {}

output "bonsai_release" {
value = data.bonsai_release.get_by_slug
}

output "bonsai_releases" {
value = data.bonsai_releases.list
}
3 changes: 3 additions & 0 deletions examples/data-sources/bonsai_release/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "bonsai_release" "get_by_slug" {
slug = "elasticsearch-6.4.2"
}
1 change: 1 addition & 0 deletions examples/data-sources/bonsai_releases/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data "bonsai_releases" "list" {}
3 changes: 3 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/omc/bonsai-api-go/v2/bonsai"
"github.com/omc/terraform-provider-bonsai/internal/release"
"github.com/omc/terraform-provider-bonsai/internal/space"
)

Expand Down Expand Up @@ -82,6 +83,8 @@ func (p *bonsaiProvider) Resources(ctx context.Context) []func() resource.Resour

func (p *bonsaiProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
release.NewDataSource,
release.NewListDataSource,
space.NewDataSource,
space.NewListDataSource,
}
Expand Down
93 changes: 93 additions & 0 deletions internal/release/data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package release

import (
"context"
"fmt"

tfds "github.com/hashicorp/terraform-plugin-framework/datasource"
dschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/omc/bonsai-api-go/v2/bonsai"
)

// dataSource is the data source implementation.
type dataSource struct {
client *bonsai.ReleaseClient
}

// Ensure the implementation satisfies the expected interfaces.
var (
_ tfds.DataSource = &dataSource{}
)

// NewDataSource is a helper function to simplify the provider implementation.
func NewDataSource() tfds.DataSource {
return &dataSource{}
}

// Metadata returns the data source type name.
func (d *dataSource) Metadata(_ context.Context, req tfds.MetadataRequest, resp *tfds.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_release"
}

// Schema defines the schema for the data source.
func (d *dataSource) Schema(_ context.Context, _ tfds.SchemaRequest, resp *tfds.SchemaResponse) {
resp.Schema = dschema.Schema{
Attributes: schemaAttributes(),
MarkdownDescription: dataSourceMarkdownDescription,
}
}

// Read refreshes the Terraform state with the latest data.
func (d *dataSource) Read(ctx context.Context, req tfds.ReadRequest, resp *tfds.ReadResponse) {
var state model

// Fetch requested Slug from context
resp.Diagnostics.Append(req.Config.GetAttribute(ctx, path.Root("slug"), &state.Slug)...)
if resp.Diagnostics.HasError() {
return
}

if state.Slug.IsNull() {
resp.Diagnostics.AddError(
fmt.Sprintf("Unable to Read Bonsai Release (%s) from the Bonsai API", state.Slug.ValueString()),
"expected 'slug' option to be set",
)
return
}

s, err := d.client.Release.GetBySlug(ctx, state.Slug.ValueString())
if err != nil {
resp.Diagnostics.AddError(
fmt.Sprintf("Unable to Read Bonsai Release (%s) from the Bonsai API", state.Slug.ValueString()),
err.Error(),
)
return
}

// Map response body to model
state = convert(s)

// Set state
diags := resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
}

// Configure adds the provider configured client to the data source.
func (d *dataSource) Configure(_ context.Context, req tfds.ConfigureRequest, resp *tfds.ConfigureResponse) {
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*bonsai.Client)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *bonsai.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)

return
}

d.client = &client.Release
}
94 changes: 94 additions & 0 deletions internal/release/data_source_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package release

import (
"context"
"fmt"

tfds "github.com/hashicorp/terraform-plugin-framework/datasource"
dschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/omc/bonsai-api-go/v2/bonsai"
)

// listDataSourceModel maps the data source schema data.
type listDataSourceModel struct {
Releases []model `tfsdk:"releases"`
}

// listDataSource is the data source implementation.
type listDataSource struct {
client *bonsai.ReleaseClient
}

// Ensure the implementation satisfies the expected interfaces.
var (
_ tfds.DataSource = &listDataSource{}
)

// NewListDataSource is a helper function to simplify the provider implementation.
func NewListDataSource() tfds.DataSource {
return &listDataSource{}
}

// Metadata returns the data source type name.
func (d *listDataSource) Metadata(_ context.Context, req tfds.MetadataRequest, resp *tfds.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_releases"
}

// Schema defines the schema for the data source.
func (d *listDataSource) Schema(_ context.Context, _ tfds.SchemaRequest, resp *tfds.SchemaResponse) {
resp.Schema = dschema.Schema{
MarkdownDescription: listDataSourceMarkdownDescription,
Attributes: map[string]dschema.Attribute{
"releases": dschema.ListNestedAttribute{
MarkdownDescription: dataSourceMarkdownDescription,
Computed: true,
NestedObject: dschema.NestedAttributeObject{
Attributes: schemaAttributes(),
},
},
},
}
}

// Read refreshes the Terraform state with the latest data.
func (d *listDataSource) Read(ctx context.Context, req tfds.ReadRequest, resp *tfds.ReadResponse) {
var state listDataSourceModel

releases, err := d.client.Release.All(ctx)
if err != nil {
resp.Diagnostics.AddError(
"Unable to Read Bonsai Releases from the Bonsai API",
err.Error(),
)
return
}

// Map response body to model
for _, s := range releases {
releaseState := convert(s)
state.Releases = append(state.Releases, releaseState)
}

// Set state
diags := resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
}

// Configure adds the provider configured client to the data source.
func (d *listDataSource) Configure(_ context.Context, req tfds.ConfigureRequest, resp *tfds.ConfigureResponse) {
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*bonsai.Client)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *bonsai.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)

return
}

d.client = &client.Release
}
27 changes: 27 additions & 0 deletions internal/release/data_source_list_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package release_test

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

func (s *ReleaseTestSuite) TestRelease_ListDataSource() {
resource.Test(s.T(), resource.TestCase{
ProtoV6ProviderFactories: s.ProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: `
data "bonsai_releases" "list" {}
output "bonsai_releases" {
value = [for s in data.bonsai_releases.list.releases : s.slug]
}
`,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.bonsai_releases.list", "releases.#", "12"),
resource.TestCheckResourceAttr("data.bonsai_releases.list", "releases.0.%", "5"),
resource.TestCheckResourceAttr("data.bonsai_releases.list", "releases.0.slug", "elasticsearch-2.4.0"),
),
},
},
})
}
32 changes: 32 additions & 0 deletions internal/release/data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package release_test

import (
"fmt"

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

func (s *ReleaseTestSuite) TestRelease_DataSource() {
const releaseSlug = "elasticsearch-5.6.16"
resource.Test(s.T(), resource.TestCase{
ProtoV6ProviderFactories: s.ProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
data "bonsai_release" "get_by_slug" {
slug = "%s"
}
output "bonsai_release_slug" {
value = data.bonsai_release.get_by_slug.slug
}
`, releaseSlug),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet("data.bonsai_release.get_by_slug", "slug"),
resource.TestCheckResourceAttr("data.bonsai_release.get_by_slug", "slug", releaseSlug),
resource.TestCheckOutput("bonsai_release_slug", releaseSlug),
),
},
},
})
}
Loading

0 comments on commit 3a13e2a

Please sign in to comment.