Skip to content

Commit

Permalink
feat: add resource to manage worker group
Browse files Browse the repository at this point in the history
  • Loading branch information
fhussonnois committed Oct 2, 2024
1 parent 68c9f60 commit b1dc21c
Show file tree
Hide file tree
Showing 6 changed files with 322 additions and 1 deletion.
2 changes: 1 addition & 1 deletion internal/provider/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (c *Client) rawResponseRequest(method string, req *http.Request) (int, []by
}
}

if (res.StatusCode != http.StatusOK) && (res.StatusCode != http.StatusNoContent) {
if (res.StatusCode != http.StatusOK) && (res.StatusCode != http.StatusCreated) && (res.StatusCode != http.StatusNoContent) {
return 0, nil, &RequestError{
StatusCode: res.StatusCode,
Err: fmt.Errorf("status: %d, method: %s, body: %s", res.StatusCode, method, bodyResult),
Expand Down
59 changes: 59 additions & 0 deletions internal/provider/data_source_worker_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package provider

import (
"context"
"fmt"

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

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

ReadContext: dataSourceUserRead,
Schema: map[string]*schema.Schema{
"id": {
Description: "The worker group id.",
Type: schema.TypeString,
Computed: true,
},
"key": {
Description: "The worker group key.",
Type: schema.TypeString,
Required: true,
},
"description": {
Description: "The worker group description.",
Type: schema.TypeString,
Computed: true,
},
"allowed_tenants": {
Description: "The list of tenants allowed to use the worker group.",
Type: schema.TypeString,
Computed: true,
},
},
}
}

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

id := d.Get("id").(string)
tenantId := c.TenantId

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

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

return diags
}
2 changes: 2 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func New(version string, tenant *string) func() *schema.Provider {
"kestra_service_account": dataSourceServiceAccount(),
"kestra_user_api_tokens": dataSourceUserApiTokens(),
"kestra_kv": dataSourceKv(),
"kestra_worker_group": dataSourceWorkerGroup(),
},
ResourcesMap: map[string]*schema.Resource{
"kestra_binding": resourceBinding(),
Expand All @@ -109,6 +110,7 @@ func New(version string, tenant *string) func() *schema.Provider {
"kestra_service_account": resourceServiceAccount(),
"kestra_user_api_token": resourceUserApiToken(),
"kestra_kv": resourceKv(),
"kestra_worker_group": resourceWorkerGroup(),
},
}

Expand Down
138 changes: 138 additions & 0 deletions internal/provider/resource_worker_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
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 resourceWorkerGroup() *schema.Resource {
return &schema.Resource{
Description: "Manages a Kestra Worker Group.",

CreateContext: resourceWorkerGroupCreate,
ReadContext: resourceWorkerGroupRead,
UpdateContext: resourceWorkerGroupUpdate,
DeleteContext: resourceWorkerGroupDelete,
Schema: map[string]*schema.Schema{
"key": {
Description: "The worker group key.",
Type: schema.TypeString,
Required: true,
},
"description": {
Description: "The worker group description.",
Type: schema.TypeString,
Optional: true,
},
"allowed_tenants": {
Description: "The list of tenants allowed to use the worker group.",
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
}
}

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

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

tenantId := c.TenantId

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

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

return diags
}

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

workerGroupId := d.Id()
tenantId := c.TenantId

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

return diag.FromErr(reqErr.Err)
}

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

return diags
}

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

if d.HasChanges("key", "description", "allowed_tenants") {
body, err := workerGroupSchemaToApi(d)
if err != nil {
return diag.FromErr(err)
}

workerGroupId := d.Id()
tenantId := c.TenantId

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

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

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

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

workerGroupId := d.Id()
tenantId := c.TenantId

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

d.SetId("")

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

import (
"fmt"
"regexp"
"testing"

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

func TestAccWorkerGroup(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: testAccResourceWorkerGroup(
"test-key",
"test-description",
"[\"test-tenant\"]",
),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"kestra_worker_group.new", "key", "test-key",
),
resource.TestCheckResourceAttr(
"kestra_worker_group.new", "description", "test-description",
),
resource.TestMatchResourceAttr(
"kestra_worker_group.new", "allowed_tenants", regexp.MustCompile(".*"),
),
),
},
{
Config: testAccResourceWorkerGroup(
"test-key",
"test-description",
"[]",
),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"kestra_worker_group.new", "key", "test-key",
),
resource.TestCheckResourceAttr(
"kestra_worker_group.new", "description", "test-description",
),
resource.TestCheckNoResourceAttr(
"kestra_worker_group.new", "allowed_tenants",
),
),
},
{
ResourceName: "kestra_worker_group.new",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccResourceWorkerGroup(key, description, tenants string) string {
return fmt.Sprintf(
`
resource "kestra_worker_group" "new" {
key = "%s"
description = "%s"
allowed_tenants = %s
}`,
key,
description,
tenants,
)

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

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

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

if d.Id() != "" {
body["id"] = d.Id()
}

body["key"] = d.Get("key").(string)
body["description"] = d.Get("description").(string)
body["allowedTenants"] = d.Get("allowed_tenants").([]interface{})

return body, nil
}

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

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

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

if _, ok := r["description"]; ok {
if r["description"].(string) != "" {
if err := d.Set("description", r["description"].(string)); err != nil {
return diag.FromErr(err)
}
}
}

if _, ok := r["allowedTenants"]; ok {
if len(r["allowedTenants"].([]interface{})) > 0 {
if err := d.Set("allowed_tenants", r["allowedTenants"].([]interface{})); err != nil {
return diag.FromErr(err)
}
}
}

return diags
}

0 comments on commit b1dc21c

Please sign in to comment.