Skip to content

Commit

Permalink
adds tembo_instance_secret data source (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
shahadarsh authored Oct 13, 2023
1 parent 9e76846 commit 7260ca4
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 1 deletion.
26 changes: 26 additions & 0 deletions docs/data-sources/instance_secret.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "tembo_instance_secret Data Source - terraform-provider-tembo"
subcategory: ""
description: |-
Data Source for Tembo Instance Secret.
---

# tembo_instance_secret (Data Source)

Data Source for Tembo Instance Secret.



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

### Required

- `instance_id` (String) Unique ID for the instance generated by Tembo
- `org_id` (String) Id of the organization in which the instance will be created
- `secret_name` (String) Secret name

### Read-Only

- `secrets` (Map of String) Secret Key/Values
10 changes: 10 additions & 0 deletions examples/resource-creation/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ data "tembo_instance_secrets" "test" {
instance_id = tembo_instance.test_db.instance_id
}

data "tembo_instance_secret" "test_sec" {
org_id = "org_2UdhszNbCVhLAXkZm30nz8pL778"
instance_id = tembo_instance.test_db.instance_id
secret_name = "readonly-role"
}


output "instance" {
value = tembo_instance.test_db
Expand All @@ -77,3 +83,7 @@ output "instance" {
output "data" {
value = data.tembo_instance_secrets.test
}

output "data_secret" {
value = data.tembo_instance_secret.test_sec
}
150 changes: 150 additions & 0 deletions internal/provider/instance_secret_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package provider

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
tembodataclient "github.com/tembo-io/terraform-provider-tembo/tembodataclient"
)

// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &temboInstanceSecret{}
_ datasource.DataSourceWithConfigure = &temboInstanceSecret{}
)

// NewTemboInstanceSecretDataSource is a helper function to simplify the provider implementation.
func NewTemboInstanceSecretDataSource() datasource.DataSource {
return &temboInstanceSecret{}
}

// TemboInstanceSecret is the data source implementation.
type temboInstanceSecret struct {
temboInstanceSecretsConfig instanceSecretsConfig
}

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

// Schema defines the schema for the data source.
func (d *temboInstanceSecret) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Data Source for Tembo Instance Secret.",
Attributes: map[string]schema.Attribute{
"org_id": schema.StringAttribute{
MarkdownDescription: "Id of the organization in which the instance will be created",
Required: true,
},
"instance_id": schema.StringAttribute{
MarkdownDescription: "Unique ID for the instance generated by Tembo",
Required: true,
},
"secret_name": schema.StringAttribute{
MarkdownDescription: "Secret name",
Required: true,
},
"secrets": schema.MapAttribute{
MarkdownDescription: "Secret Key/Values",
Computed: true,
ElementType: types.StringType,
},
},
}
}

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

temboInstanceSecretConfig, ok := req.ProviderData.(instanceSecretsConfig)

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

return
}

d.temboInstanceSecretsConfig = temboInstanceSecretConfig
}

// temboInstanceSecretModel maps the data source schema data.
type temboInstanceSecretModel struct {
OrgId types.String `tfsdk:"org_id"`
InstanceId types.String `tfsdk:"instance_id"`
SecretName types.String `tfsdk:"secret_name"`
Secrets map[string]types.String `tfsdk:"secrets"`
}

// Read refreshes the Terraform state with the latest data.
func (d *temboInstanceSecret) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// Get current state
var state temboInstanceSecretModel

ctx = context.WithValue(ctx, tembodataclient.ContextAccessToken, d.temboInstanceSecretsConfig.accessToken)

var orgId string
resp.Diagnostics.Append(req.Config.GetAttribute(ctx, path.Root("org_id"), &orgId)...)

var instanceId string
resp.Diagnostics.Append(req.Config.GetAttribute(ctx, path.Root("instance_id"), &instanceId)...)

var secretName string
resp.Diagnostics.Append(req.Config.GetAttribute(ctx, path.Root("secret_name"), &secretName)...)

if resp.Diagnostics.HasError() {
tflog.Error(ctx, fmt.Sprintf("error reading terraform plan %v", resp.Diagnostics.Errors()))
return
}

availableSecrets, _, err := d.temboInstanceSecretsConfig.client.SecretsApi.GetSecretNamesV1(ctx, orgId, instanceId).Execute()
if err != nil {
resp.Diagnostics.AddError(
"Unable to Read Tembo Instance Available Secrets",
err.Error(),
)
return
}

// Get refreshed Instance value from API
secret, _, err := d.temboInstanceSecretsConfig.client.SecretsApi.GetSecretV1(ctx, orgId, instanceId, secretName).Execute()
if err != nil {
resp.Diagnostics.AddError(
"Unable to Read Tembo Instance Secret",
err.Error(),
)
return
}

localSecret := make(map[string]types.String)

if len(availableSecrets) > 0 {
for _, aSecret := range availableSecrets {
if aSecret.Name == secretName {
for _, possibleKey := range aSecret.PossibleKeys {
localSecret[possibleKey] = types.StringValue(secret[possibleKey])
}
state.Secrets = localSecret
}
}
}

// Set refreshed state
diags := resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
44 changes: 44 additions & 0 deletions internal/provider/instance_secret_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package provider

import (
"fmt"
"os"
"testing"

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

func TestInstanceSecretDataSource(t *testing.T) {
instanceName := generateInstanceName()
orgId := os.Getenv("ORG_ID")

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Read testing
{
Config: testProviderConfig() + testInstanceResourceCreateConfig(instanceName, orgId) + testInstanceSecretCreateConfig(orgId),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet("data.tembo_instance_secret.test_readonly", "secrets.username"),
resource.TestCheckResourceAttrSet("data.tembo_instance_secret.test_readonly", "secrets.password"),
resource.TestCheckResourceAttrSet("data.tembo_instance_secret.test_certificate", "secrets.ca.crt"),
),
},
},
})
}

func testInstanceSecretCreateConfig(orgId string) string {
return fmt.Sprintf(`
data "tembo_instance_secret" "test_readonly" {
org_id = "%v"
instance_id = tembo_instance.test.instance_id
secret_name = "readonly-role"
}
data "tembo_instance_secret" "test_certificate" {
org_id = "%v"
instance_id = tembo_instance.test.instance_id
secret_name = "certificate"
}
`, orgId, orgId)
}
2 changes: 1 addition & 1 deletion internal/provider/instance_secrets_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (d *temboInstanceSecretsDataSource) Read(ctx context.Context, req datasourc
return
}

// Get refreshed Instance value from API
// Get Secret value from API
availableSecrets, _, err := d.temboInstanceSecretsConfig.client.SecretsApi.GetSecretNamesV1(ctx, orgId, instanceId).Execute()
if err != nil {
resp.Diagnostics.AddError(
Expand Down
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ func (p *temboProvider) Configure(ctx context.Context, req provider.ConfigureReq
func (p *temboProvider) DataSources(_ context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
NewTemboInstanceSecretsDataSource,
NewTemboInstanceSecretDataSource,
}
}

Expand Down

0 comments on commit 7260ca4

Please sign in to comment.