Skip to content

Commit

Permalink
adds support for import for tembo_instance resource (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
shahadarsh authored Oct 25, 2023
1 parent ee5ad98 commit b0b5311
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 31 deletions.
110 changes: 106 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,104 @@ The Terraform provider for [Tembo](https://tembo.io/)
terraform {
required_providers {
tembo = {
source = "registry.terraform.io/tembo-io/tembo"
source = "tembo-io/tembo"
version = ">= 0.1.0"
}
}
}
provider "tembo" {}
provider "tembo" {
}
resource "tembo_instance" "test_db" {
instance_name = "tfprovider-de2345"
org_id = "org_test" # Replace this with your Tembo organization id
cpu = "1"
stack_type = "Standard"
environment = "dev"
memory = "4Gi"
storage = "10Gi"
replicas = 1
# ip_allow_list = ["71.190.46.69"]
# extra_domains_rw = ["sample-invalid-domain.test.tembo-development.com"]
postgres_configs = [
{
name = "max_connections"
value = "200"
},
{
name = "wal_buffers"
value = "16MB"
}
]
trunk_installs = [
{
name = "pgmq"
version = "0.24.0"
}
]
extensions = [{
name = "plperl"
description = "PL/Perl procedural language"
locations = [{
database = "app"
schema = "public"
version = "1.0"
enabled = false
},
{
database = "postgres"
schema = "public"
version = "1.0"
enabled = true
}]
},
{
"name" : "pltclu",
"description" : "PL/TclU untrusted procedural language",
"locations" : [
{
"database" : "app",
"schema" : "public",
"version" : "1.0",
"enabled" : false,
"error" : false,
"error_message" : null
},
{
"database" : "postgres",
"schema" : "public",
"version" : "1.0",
"enabled" : false,
"error" : false,
"error_message" : null
}
]
}]
}
data "tembo_instance_secrets" "test" {
org_id = "org_test" # Replace this with your Tembo organization id
instance_id = tembo_instance.test_db.instance_id
}
data "tembo_instance_secret" "test_sec" {
org_id = "org_test" # Replace this with your Tembo organization id
instance_id = tembo_instance.test_db.instance_id
secret_name = "readonly-role"
}
output "instance" {
value = tembo_instance.test_db
}
data "tembo_example" "example" {}
output "data" {
value = data.tembo_instance_secrets.test
}
output "data_secret" {
value = data.tembo_instance_secret.test_sec
}
```

## Developing the Provider
Expand All @@ -45,14 +135,26 @@ make testacc

Install OpenAPI Generator if not already by following steps [here](https://openapi-generator.tech/docs/installation)

### Control plane API client

Go to `internal/provider/temboclient` directory in your terminal.

Run following command to re-generate the go client code for the API. You might want to delete the contents of the directory first.
Delete the contents of the directory first and then run following command to re-generate the go client code for the API.

```bash
openapi-generator generate -i https://api.coredb.io/api-docs/openapi.json -g go -o . --additional-properties=packageName=temboclient
```

### Data plane API client

Go to `internal/provider/tembodataclient` directory in your terminal.

Delete the contents of the directory first and then run following command to re-generate the go client code for the API.

```bash
openapi-generator generate -i https://api.data-1.use1.tembo.io/api-docs/openapi.json -g go -o . --additional-properties=packageName=tembodataclient
```

## Releasing the Provider to Terraform Registry

The GitHub Action will trigger and create a release for your provider whenever a new valid version tag is pushed to the repository. Terraform provider versions must follow the [Semantic Versioning](https://semver.org/) standard (vMAJOR.MINOR.PATCH).
Expand Down
19 changes: 17 additions & 2 deletions internal/provider/instance_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"fmt"
"io"
"net/http"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
Expand All @@ -22,8 +24,9 @@ import (

// Ensure the implementation satisfies the expected interfaces.
var (
_ resource.Resource = &temboInstanceResource{}
_ resource.ResourceWithConfigure = &temboInstanceResource{}
_ resource.Resource = &temboInstanceResource{}
_ resource.ResourceWithConfigure = &temboInstanceResource{}
_ resource.ResourceWithImportState = &temboInstanceResource{}
)

var (
Expand Down Expand Up @@ -483,6 +486,18 @@ func (r *temboInstanceResource) Delete(ctx context.Context, req resource.DeleteR
}
}

func (r *temboInstanceResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
parts := strings.Split(req.ID, "/")
if len(parts) != 2 {
resp.Diagnostics.AddError("Resource Import Invalid ID", fmt.Sprintf("wrong format of import ID (%s), use: 'org_id/instance_id'", req.ID))
return
}
orgId := parts[0]
instanceId := parts[1]
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("org_id"), orgId)...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), instanceId)...)
}

func setTemboInstanceResourceModel(instanceResourceModel *temboInstanceResourceModel,
instance *temboclient.Instance, isUpdateMode bool, diagnostics *diag.Diagnostics) {
if isUpdateMode {
Expand Down
79 changes: 54 additions & 25 deletions internal/provider/instance_resource_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package provider

import (
"errors"
"fmt"
"math/rand"
"os"
"testing"
"time"

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

func TestTemboInstanceResource(t *testing.T) {

instanceName := generateInstanceName()
orgId := os.Getenv("ORG_ID")
resourceName := "tembo_instance.test"

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Expand All @@ -22,37 +25,45 @@ func TestTemboInstanceResource(t *testing.T) {
{
Config: testProviderConfig() + testInstanceResourceCreateConfig(instanceName, orgId),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("tembo_instance.test", "instance_name", instanceName),
resource.TestCheckResourceAttr("tembo_instance.test", "org_id", orgId),
resource.TestCheckResourceAttr("tembo_instance.test", "cpu", "1"),
resource.TestCheckResourceAttr("tembo_instance.test", "stack_type", "Standard"),
resource.TestCheckResourceAttr("tembo_instance.test", "replicas", "1"),
resource.TestCheckResourceAttr("tembo_instance.test", "environment", "dev"),
resource.TestCheckResourceAttr("tembo_instance.test", "memory", "4Gi"),
resource.TestCheckResourceAttr("tembo_instance.test", "storage", "10Gi"),
resource.TestCheckResourceAttrSet("tembo_instance.test", "instance_id"),
resource.TestCheckResourceAttrSet("tembo_instance.test", "last_updated"),
resource.TestCheckResourceAttr("tembo_instance.test", "ip_allow_list.#", "1"),
//resource.TestCheckResourceAttr("tembo_instance.test", "postgres_configs.#", "1"),
resource.TestCheckResourceAttr(resourceName, "instance_name", instanceName),
resource.TestCheckResourceAttr(resourceName, "org_id", orgId),
resource.TestCheckResourceAttr(resourceName, "cpu", "1"),
resource.TestCheckResourceAttr(resourceName, "stack_type", "Standard"),
resource.TestCheckResourceAttr(resourceName, "replicas", "1"),
resource.TestCheckResourceAttr(resourceName, "environment", "dev"),
resource.TestCheckResourceAttr(resourceName, "memory", "4Gi"),
resource.TestCheckResourceAttr(resourceName, "storage", "10Gi"),
resource.TestCheckResourceAttrSet(resourceName, "instance_id"),
resource.TestCheckResourceAttrSet(resourceName, "last_updated"),
resource.TestCheckResourceAttr(resourceName, "ip_allow_list.#", "1"),
resource.TestCheckResourceAttr(resourceName, "postgres_configs.#", "1"),
),
},
// TODO: Add ImportState testing
// ImportState testing
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIdentifierAttribute: "instance_id",
ImportStateIdFunc: testTemboInstanceClientImportStateIDFunc(resourceName),
ImportStateVerifyIgnore: []string{"last_updated", "trunk_installs", "extensions"},
},
// Update and Read testing
{
Config: testProviderConfig() + testInstanceResourceUpdateConfig(instanceName, orgId),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("tembo_instance.test", "instance_name", instanceName),
resource.TestCheckResourceAttr("tembo_instance.test", "org_id", orgId),
resource.TestCheckResourceAttr("tembo_instance.test", "cpu", "2"),
resource.TestCheckResourceAttr("tembo_instance.test", "stack_type", "Standard"),
resource.TestCheckResourceAttr("tembo_instance.test", "replicas", "2"),
resource.TestCheckResourceAttr("tembo_instance.test", "environment", "dev"),
resource.TestCheckResourceAttr("tembo_instance.test", "memory", "8Gi"),
resource.TestCheckResourceAttr("tembo_instance.test", "storage", "10Gi"),
resource.TestCheckResourceAttrSet("tembo_instance.test", "instance_id"),
resource.TestCheckResourceAttrSet("tembo_instance.test", "last_updated"),
resource.TestCheckResourceAttr("tembo_instance.test", "ip_allow_list.#", "2"),
//resource.TestCheckResourceAttr("tembo_instance.test", "postgres_configs.#", "2"),
resource.TestCheckResourceAttr(resourceName, "instance_name", instanceName),
resource.TestCheckResourceAttr(resourceName, "org_id", orgId),
resource.TestCheckResourceAttr(resourceName, "cpu", "2"),
resource.TestCheckResourceAttr(resourceName, "stack_type", "Standard"),
resource.TestCheckResourceAttr(resourceName, "replicas", "2"),
resource.TestCheckResourceAttr(resourceName, "environment", "dev"),
resource.TestCheckResourceAttr(resourceName, "memory", "8Gi"),
resource.TestCheckResourceAttr(resourceName, "storage", "10Gi"),
resource.TestCheckResourceAttrSet(resourceName, "instance_id"),
resource.TestCheckResourceAttrSet(resourceName, "last_updated"),
resource.TestCheckResourceAttr(resourceName, "ip_allow_list.#", "2"),
resource.TestCheckResourceAttr(resourceName, "postgres_configs.#", "2"),
),
},
// Delete testing automatically occurs in TestCase
Expand Down Expand Up @@ -185,3 +196,21 @@ func generateInstanceName() string {
}
return fmt.Sprintf("tf-test-%v", string(b))
}

func testTemboInstanceClientImportStateIDFunc(resourceName string) resource.ImportStateIdFunc {
return func(s *terraform.State) (string, error) {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return "", fmt.Errorf("Not found: %s", resourceName)
}

if rs.Primary.ID == "" {
return "", errors.New("No Tembo Instance ID set")
}

orgId := rs.Primary.Attributes["org_id"]
instanceId := rs.Primary.Attributes["instance_id"]

return fmt.Sprintf("%s/%s", orgId, instanceId), nil
}
}

0 comments on commit b0b5311

Please sign in to comment.