Skip to content

Commit

Permalink
feat: add tenant
Browse files Browse the repository at this point in the history
  • Loading branch information
tchiotludo committed Oct 19, 2023
1 parent 96b8c3b commit 1a91ed8
Show file tree
Hide file tree
Showing 10 changed files with 352 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .github/docker/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ kestra:
password: foo
templates:
enabled: true
ee:
tenants:
enabled: true
7 changes: 6 additions & 1 deletion .github/workflows/index.jsonl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{ "index" : { "_index" : "kestra_roles", "_id" : "admin" } }
{"id":"admin","name":"Admin","permissions":{"FLOW":["READ","CREATE","UPDATE","DELETE"],"TEMPLATE":["READ","CREATE","UPDATE","DELETE"],"EXECUTION":["READ","CREATE","UPDATE","DELETE"],"USER":["READ","CREATE","UPDATE","DELETE"],"NAMESPACE":["READ","CREATE","UPDATE","DELETE"],"GROUP":["READ","CREATE","UPDATE","DELETE"],"ROLE":["READ","CREATE","UPDATE","DELETE"],"AUDITLOG":["READ"],"SECRET":["READ","CREATE","UPDATE","DELETE"],"BINDING":["READ","CREATE","UPDATE","DELETE"]},"deleted":false}
{"id":"admin","name":"Admin","permissions":{"FLOW":["READ","CREATE","UPDATE","DELETE"],"TEMPLATE":["READ","CREATE","UPDATE","DELETE"],"EXECUTION":["READ","CREATE","UPDATE","DELETE"],"USER":["READ","CREATE","UPDATE","DELETE"],"NAMESPACE":["READ","CREATE","UPDATE","DELETE"],"GROUP":["READ","CREATE","UPDATE","DELETE"],"ROLE":["READ","CREATE","UPDATE","DELETE"],"AUDITLOG":["READ"],"SECRET":["READ","CREATE","UPDATE","DELETE"],"BINDING":["READ","CREATE","UPDATE","DELETE"],"TENANT":["READ","CREATE","UPDATE","DELETE"]},"deleted":false}
{"id":"admin","name":"Admin","tenantId":"unit_test","permissions":{"FLOW":["READ","CREATE","UPDATE","DELETE"],"TEMPLATE":["READ","CREATE","UPDATE","DELETE"],"EXECUTION":["READ","CREATE","UPDATE","DELETE"],"USER":["READ","CREATE","UPDATE","DELETE"],"NAMESPACE":["READ","CREATE","UPDATE","DELETE"],"GROUP":["READ","CREATE","UPDATE","DELETE"],"ROLE":["READ","CREATE","UPDATE","DELETE"],"AUDITLOG":["READ"],"SECRET":["READ","CREATE","UPDATE","DELETE"],"BINDING":["READ","CREATE","UPDATE","DELETE"],"TENANT":["READ","CREATE","UPDATE","DELETE"]},"deleted":false}
{ "index" : { "_index" : "kestra_groups", "_id" : "admin" } }
{"id":"admin","name":"Group Admin","description":"My description","deleted":false}
{ "index" : { "_index" : "kestra_users", "_id" : "john" } }
Expand All @@ -12,3 +13,7 @@
{"id":"simple","namespace":"io.kestra.terraform.data","tasks":[{"id":"t1","type":"io.kestra.core.tasks.log.Log","message":"first {{task.id}}","level":"TRACE"},{"id":"t2","type":"io.kestra.core.tasks.log.Log","disabled":true,"message":"second {{task.type}}","level":"WARN"},{"id":"t3","type":"io.kestra.core.tasks.log.Log","message":"third {{flow.id}}","level":"ERROR"}],"deleted":false}
{ "index" : { "_index" : "kestra_bindings", "_id" : "john" } }
{"id":"john","type":"USER","externalId":"john","roleId":"admin","deleted":false}
{"id":"john","type":"USER","externalId":"john","roleId":"admin","tenantId":"unit_test","deleted":false}
{ "index" : { "_index" : "kestra_tenants", "_id" : "admin" } }
{"id":"admin","name":"My admin tenants","deleted":false}
{"id":"unit_test","name":"Unit test Tenants","deleted":false}
25 changes: 25 additions & 0 deletions docs/data-sources/tenant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "kestra_tenant Data Source - terraform-provider-kestra"
subcategory: ""
description: |-
Use this data source to access information about an existing Kestra Tenant.
---

# kestra_tenant (Data Source)

Use this data source to access information about an existing Kestra Tenant.



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

### Required

- `tenant_id` (String) The tenant id.

### Read-Only

- `id` (String) The ID of this resource.
- `name` (String) The tenant name.
28 changes: 28 additions & 0 deletions docs/resources/tenant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "kestra_tenant Resource - terraform-provider-kestra"
subcategory: ""
description: |-
Manages a Kestra Tenant.
---

# kestra_tenant (Resource)

Manages a Kestra Tenant.



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

### Required

- `tenant_id` (String) The tenant id.

### Optional

- `name` (String) The tenant name.

### Read-Only

- `id` (String) The ID of this resource.
48 changes: 48 additions & 0 deletions internal/provider/data_source_tenant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package provider

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceTenant() *schema.Resource {
return &schema.Resource{
Description: "Use this data source to access information about an existing Kestra Tenant.",

ReadContext: dataSourceTenantRead,
Schema: map[string]*schema.Schema{
"tenant_id": {
Description: "The tenant id.",
Type: schema.TypeString,
Required: true,
},
"name": {
Description: "The tenant name.",
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceTenantRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
c := meta.(*Client)
var diags diag.Diagnostics

tenantId := d.Get("tenant_id").(string)

r, reqErr := c.request("GET", fmt.Sprintf("%s/tenants/%s", apiRoot(""), tenantId), nil)
if reqErr != nil {
return diag.FromErr(reqErr.Err)
}

errs := tenantApiToSchema(r.(map[string]interface{}), d)
if errs != nil {
return errs
}

return diags
}
36 changes: 36 additions & 0 deletions internal/provider/data_source_tenant_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package provider

import (
"fmt"
"regexp"
"testing"

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

func TestAccDataSourceTenant(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: testAccDataSourceTenant("admin"),
Check: resource.ComposeTestCheckFunc(
resource.TestMatchResourceAttr(
"data.kestra_tenant.new", "id", regexp.MustCompile("admin"),
),
),
},
},
})
}

func testAccDataSourceTenant(id string) string {
return fmt.Sprintf(
`
data "kestra_tenant" "new" {
tenant_id = "%s"
}`,
id,
)
}
2 changes: 2 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func New(version string) func() *schema.Provider {
"kestra_role": dataSourceRole(),
"kestra_template": dataSourceTemplate(),
"kestra_user": dataSourceUser(),
"kestra_tenant": dataSourceTenant(),
},
ResourcesMap: map[string]*schema.Resource{
"kestra_binding": resourceBinding(),
Expand All @@ -75,6 +76,7 @@ func New(version string) func() *schema.Provider {
"kestra_template": resourceTemplate(),
"kestra_user": resourceUser(),
"kestra_user_password": resourceUserPassword(),
"kestra_tenant": resourceTenant(),
},
}

Expand Down
126 changes: 126 additions & 0 deletions internal/provider/resource_tenant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package provider

import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"net/http"
)

func resourceTenant() *schema.Resource {
return &schema.Resource{
Description: "Manages a Kestra Tenant.",

CreateContext: resourceTenantCreate,
ReadContext: resourceTenantRead,
UpdateContext: resourceTenantUpdate,
DeleteContext: resourceTenantDelete,
Schema: map[string]*schema.Schema{
"tenant_id": {
Description: "The tenant id.",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"name": {
Description: "The tenant name.",
Type: schema.TypeString,
Optional: true,
},
},
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
}
}

func resourceTenantCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
c := meta.(*Client)
var diags diag.Diagnostics

body, err := tenantSchemaToApi(d)
if err != nil {
return diag.FromErr(err)
}

r, reqErr := c.request("POST", fmt.Sprintf("%s/tenants", apiRoot("")), body)
if reqErr != nil {
return diag.FromErr(reqErr.Err)
}

errs := tenantApiToSchema(r.(map[string]interface{}), d)
if errs != nil {
return errs
}

return diags
}

func resourceTenantRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
c := meta.(*Client)
var diags diag.Diagnostics

tenantId := d.Id()

r, reqErr := c.request("GET", fmt.Sprintf("%s/tenants/%s", apiRoot(""), tenantId), nil)
if reqErr != nil {
if reqErr.StatusCode == http.StatusNotFound {
d.SetId("")
return diags
}

return diag.FromErr(reqErr.Err)
}

errs := tenantApiToSchema(r.(map[string]interface{}), d)
if errs != nil {
return errs
}

return diags
}

func resourceTenantUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
c := meta.(*Client)
var diags diag.Diagnostics

if d.HasChanges("name") {
body, err := tenantSchemaToApi(d)
if err != nil {
return diag.FromErr(err)
}

tenantId := d.Id()

r, reqErr := c.request("PUT", fmt.Sprintf("%s/tenants/%s", apiRoot(""), tenantId), body)
if err != nil {
return diag.FromErr(reqErr.Err)
}

errs := tenantApiToSchema(r.(map[string]interface{}), d)
if errs != nil {
return errs
}

return diags
} else {
return resourceTenantRead(ctx, d, meta)
}
}

func resourceTenantDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
c := meta.(*Client)
var diags diag.Diagnostics

tenantId := d.Id()

_, reqErr := c.request("DELETE", fmt.Sprintf("%s/tenants/%s", apiRoot(""), tenantId), nil)
if reqErr != nil {
return diag.FromErr(reqErr.Err)
}

d.SetId("")

return diags
}
48 changes: 48 additions & 0 deletions internal/provider/resource_tenant_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package provider

import (
"fmt"
"testing"

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

func TestAccTenant(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: testAccResourceTenant(
"custom",
"My custom tenant",
),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"kestra_tenant.new", "tenant_id", "custom",
),
resource.TestCheckResourceAttr(
"kestra_tenant.new", "name", "My custom tenant",
),
),
},
{
ResourceName: "kestra_tenant.new",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccResourceTenant(id, name string) string {
return fmt.Sprintf(
`
resource "kestra_tenant" "new" {
tenant_id = "%s"
name = "%s"
}`,
id,
name,
)
}
30 changes: 30 additions & 0 deletions internal/provider/utils_tenant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package provider

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func tenantSchemaToApi(d *schema.ResourceData) (map[string]interface{}, error) {
body := make(map[string]interface{}, 0)

body["id"] = d.Get("tenant_id").(string)
body["name"] = d.Get("name").(string)

return body, nil
}

func tenantApiToSchema(r map[string]interface{}, d *schema.ResourceData) diag.Diagnostics {
var diags diag.Diagnostics

d.SetId(r["id"].(string))

if err := d.Set("tenant_id", r["id"].(string)); err != nil {
return diag.FromErr(err)
}
if err := d.Set("name", r["name"].(string)); err != nil {
return diag.FromErr(err)
}

return diags
}

0 comments on commit 1a91ed8

Please sign in to comment.