Skip to content

Commit

Permalink
feat: metabase
Browse files Browse the repository at this point in the history
fix: Read for tests
  • Loading branch information
LeCrabe committed Dec 16, 2024
1 parent d9df803 commit e076a7b
Show file tree
Hide file tree
Showing 12 changed files with 435 additions and 4 deletions.
31 changes: 31 additions & 0 deletions docs/resources/metabase.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "clevercloud_metabase Resource - terraform-provider-clevercloud"
subcategory: ""
description: |-
Manage Metabase https://www.metabase.com/ product.
---

# clevercloud_metabase (Resource)

Manage [Metabase](https://www.metabase.com/) product.



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

### Required

- `name` (String) Name of the service
- `plan` (String) Database size and spec

### Optional

- `region` (String) Geographical region where the data will be stored

### Read-Only

- `creation_date` (Number) Date of database creation
- `host` (String) Database host, used to connect to
- `id` (String) Generated unique identifier
2 changes: 1 addition & 1 deletion docs/resources/nodejs.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,4 @@ Optional:
- `pre_build` (String) [CC_PRE_BUILD_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#pre-build-cc_pre_build_hook)
- `pre_run` (String) [CC_PRE_RUN_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#pre-run-cc_pre_run_hook)
- `run_failed` (String) [CC_RUN_FAILED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
- `run_succeed` (String) [CC_RUN_SUCCEEDED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
- `run_succeed` (String) [CC_RUN_SUCCEEDED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
2 changes: 1 addition & 1 deletion docs/resources/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,4 @@ Optional:
- `pre_build` (String) [CC_PRE_BUILD_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#pre-build-cc_pre_build_hook)
- `pre_run` (String) [CC_PRE_RUN_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#pre-run-cc_pre_run_hook)
- `run_failed` (String) [CC_RUN_FAILED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
- `run_succeed` (String) [CC_RUN_SUCCEEDED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
- `run_succeed` (String) [CC_RUN_SUCCEEDED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
2 changes: 1 addition & 1 deletion docs/resources/scala.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,4 @@ Optional:
- `pre_build` (String) [CC_PRE_BUILD_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#pre-build-cc_pre_build_hook)
- `pre_run` (String) [CC_PRE_RUN_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#pre-run-cc_pre_run_hook)
- `run_failed` (String) [CC_RUN_FAILED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
- `run_succeed` (String) [CC_RUN_SUCCEEDED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
- `run_succeed` (String) [CC_RUN_SUCCEEDED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
2 changes: 1 addition & 1 deletion docs/resources/static.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,4 @@ Optional:
- `pre_build` (String) [CC_PRE_BUILD_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#pre-build-cc_pre_build_hook)
- `pre_run` (String) [CC_PRE_RUN_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#pre-run-cc_pre_run_hook)
- `run_failed` (String) [CC_RUN_FAILED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
- `run_succeed` (String) [CC_RUN_SUCCEEDED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
- `run_succeed` (String) [CC_RUN_SUCCEEDED_HOOK](https://www.clever-cloud.com/doc/develop/build-hooks/#run-succeeded-cc_run_succeeded_hook-or-failed-cc_run_failed_hook)
2 changes: 2 additions & 0 deletions pkg/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"go.clever-cloud.com/terraform-provider/pkg/resources/java"
"go.clever-cloud.com/terraform-provider/pkg/resources/keycloak"
"go.clever-cloud.com/terraform-provider/pkg/resources/materiakv"
"go.clever-cloud.com/terraform-provider/pkg/resources/metabase"
"go.clever-cloud.com/terraform-provider/pkg/resources/mongodb"
"go.clever-cloud.com/terraform-provider/pkg/resources/nodejs"
"go.clever-cloud.com/terraform-provider/pkg/resources/php"
Expand All @@ -27,6 +28,7 @@ var Resources = []func() resource.Resource{
cellar.NewResourceCellar,
java.NewResourceJava("war"),
materiakv.NewResourceMateriaKV,
metabase.NewResourceMetabase,
mongodb.NewResourceMongoDB,
nodejs.NewResourceNodeJS,
php.NewResourcePHP,
Expand Down
188 changes: 188 additions & 0 deletions pkg/resources/metabase/crud.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package metabase

import (
"context"
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"go.clever-cloud.com/terraform-provider/pkg"
"go.clever-cloud.com/terraform-provider/pkg/provider"
"go.clever-cloud.com/terraform-provider/pkg/tmp"
)

// Weird behaviour, but TF can ask for a Resource without having configured a Provider (maybe for Meta and Schema)
// So we need to handle the case there is no ProviderData
func (r *ResourceMetabase) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
tflog.Debug(ctx, "ResourceMetabase.Configure()")

// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}

provider, ok := req.ProviderData.(provider.Provider)
if ok {
r.cc = provider.Client()
r.org = provider.Organization()
}
}

// Create a new resource
func (r *ResourceMetabase) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
mb := Metabase{}

resp.Diagnostics.Append(req.Plan.Get(ctx, &mb)...)
if resp.Diagnostics.HasError() {
return
}

addonsProvidersRes := tmp.GetAddonsProviders(ctx, r.cc)
if addonsProvidersRes.HasError() {
resp.Diagnostics.AddError("failed to get addon providers", addonsProvidersRes.Error().Error())
return
}

addonsProviders := addonsProvidersRes.Payload()
prov := pkg.LookupAddonProvider(*addonsProviders, "metabase")
plan := pkg.LookupProviderPlan(prov, mb.Plan.ValueString())
if plan == nil || plan.ID == "" {
resp.Diagnostics.AddError("failed to find plan", "expect: "+strings.Join(pkg.ProviderPlansAsList(prov), ", ")+", got: "+mb.Plan.String())
return
}

addonReq := tmp.AddonRequest{
Name: mb.Name.ValueString(),
Plan: plan.ID,
ProviderID: "metabase",
Region: mb.Region.ValueString(),
}

res := tmp.CreateAddon(ctx, r.cc, r.org, addonReq)
if res.HasError() {
resp.Diagnostics.AddError("failed to create addon", res.Error().Error())
return
}

mb.ID = pkg.FromStr(res.Payload().ID)
mb.CreationDate = pkg.FromI(res.Payload().CreationDate)
// mb.Plan = pkg.FromStr(res.Payload().Plan.Slug)

resp.Diagnostics.Append(resp.State.Set(ctx, mb)...)
if resp.Diagnostics.HasError() {
return
}

mbInfoRes := tmp.GetAddonEnv(ctx, r.cc, r.org, mb.ID.ValueString())
if mbInfoRes.HasError() {
resp.Diagnostics.AddError("failed to get Metabase connection infos", mbInfoRes.Error().Error())
return
}

addonMB := *mbInfoRes.Payload()
tflog.Debug(ctx, "API response", map[string]interface{}{
"payload": fmt.Sprintf("%+v", addonMB),
})

hostEnvVar := pkg.First(addonMB, func(v tmp.EnvVar) bool {
return v.Name == "METABASE_URL"
})
if hostEnvVar == nil {
resp.Diagnostics.AddError("cannot get Metabase infos", "missing METABASE_URL env var on created addon")
return
}

mb.Host = pkg.FromStr(hostEnvVar.Value)

resp.Diagnostics.Append(resp.State.Set(ctx, mb)...)
if resp.Diagnostics.HasError() {
return
}
}

// Read resource information
func (r *ResourceMetabase) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
tflog.Debug(ctx, "Metabase READ", map[string]interface{}{"request": req})

var mb Metabase
diags := req.State.Get(ctx, &mb)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

addonMBRes := tmp.GetMetabase(ctx, r.cc, mb.ID.ValueString())
if addonMBRes.IsNotFoundError() {
diags = resp.State.SetAttribute(ctx, path.Root("id"), types.StringUnknown())
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
// if addonMBRes.IsNotFoundError() {
// resp.State.RemoveResource(ctx)
// return
// }
// if addonMBRes.HasError() {
// resp.Diagnostics.AddError("failed to get Metabase resource", addonMBRes.Error().Error())
// }

addonMB := addonMBRes.Payload()

if addonMB.Status == "TO_DELETE" {
resp.State.RemoveResource(ctx)
return
}
tflog.Debug(ctx, "STATE", map[string]interface{}{"mb": mb})
tflog.Debug(ctx, "API", map[string]interface{}{"mb": addonMB})
// mb.Host = pkg.FromStr(addonMB.Applications[0].Host)
// mb.Port = pkg.FromI(int64(addonMB.Port))
// mb.User = pkg.FromStr(addonMB.User)
// mb.Password = pkg.FromStr(addonMB.Password)

diags = resp.State.Set(ctx, mb)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}

// Update resource
func (r *ResourceMetabase) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
// TODO
}

// Delete resource
func (r *ResourceMetabase) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var mb Metabase

diags := req.State.Get(ctx, &mb)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
tflog.Debug(ctx, "Metabase DELETE", map[string]interface{}{"mb": mb})

res := tmp.DeleteAddon(ctx, r.cc, r.org, mb.ID.ValueString())
if res.IsNotFoundError() {
resp.State.RemoveResource(ctx)
return
}
if res.HasError() {
resp.Diagnostics.AddError("failed to delete addon", res.Error().Error())
return
}

resp.State.RemoveResource(ctx)
}

// Import resource
func (r *ResourceMetabase) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
// Save the import identifier in the id attribute
// and call Read() to fill fields
attr := path.Root("id")
resource.ImportStatePassthroughID(ctx, attr, req, resp)
}
1 change: 1 addition & 0 deletions pkg/resources/metabase/doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Manage [Metabase](https://www.metabase.com/) product.
21 changes: 21 additions & 0 deletions pkg/resources/metabase/metabase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package metabase

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/resource"
"go.clever-cloud.dev/client"
)

type ResourceMetabase struct {
cc *client.Client
org string
}

func NewResourceMetabase() resource.Resource {
return &ResourceMetabase{}
}

func (r *ResourceMetabase) Metadata(ctx context.Context, req resource.MetadataRequest, res *resource.MetadataResponse) {
res.TypeName = req.ProviderTypeName + "_metabase"
}
Loading

0 comments on commit e076a7b

Please sign in to comment.