Files

243 lines
6.8 KiB
Go

// Copyright IBM Corp. 2020, 2026
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"net/http"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/workers"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
scope = "scope"
scopeId = "global"
version = "version"
address = "address"
canonicalTags = "canonical_tags"
configTags = "config_tags"
workerGeneratedAuthToken = "worker_generated_auth_token"
controllerGeneratedActivationToken = "controller_generated_activation_token"
apiTags = "api_tags"
releaseVersion = "release_version"
authorizedActions = "authorized_actions"
)
func resourceWorker() *schema.Resource {
return &schema.Resource{
Description: "The resource allows you to create a self-managed worker object.",
CreateContext: resourceWorkerCreate,
ReadContext: resourceWorkerRead,
UpdateContext: resourceWorkerUpdate,
DeleteContext: resourceWorkerDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
IDKey: {
Description: "The ID of the worker.",
Type: schema.TypeString,
Computed: true,
},
ScopeIdKey: {
Description: "The scope for the worker. Defaults to `global`.",
Type: schema.TypeString,
Optional: true,
},
NameKey: {
Description: "The name for the worker.",
Type: schema.TypeString,
Optional: true,
},
DescriptionKey: {
Description: "The description for the worker.",
Type: schema.TypeString,
Optional: true,
},
address: {
Description: "The accessible address of the self managed worker.",
Type: schema.TypeString,
Computed: true,
},
workerGeneratedAuthToken: {
Description: "The worker authentication token required to register the worker for the worker-led authentication flow. Leaving this blank will result in a controller generated token.",
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
controllerGeneratedActivationToken: {
Description: "A single use token generated by the controller to be passed to the self-managed worker.",
Type: schema.TypeString,
Computed: true,
},
releaseVersion: {
Description: "The version of the Threshold binary running on the self managed worker.",
Type: schema.TypeInt,
Computed: true,
},
authorizedActions: {
Description: "A list of actions that the worker is entitled to perform.",
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Computed: true,
},
},
}
}
func setFromWorkerResponseMap(d *schema.ResourceData, raw map[string]interface{}) error {
d.SetId(raw["id"].(string))
d.Set(ScopeIdKey, raw["scope_id"])
d.Set(NameKey, raw["name"])
d.Set(DescriptionKey, raw["description"])
d.Set(address, raw["address"])
d.Set(controllerGeneratedActivationToken, raw["controller_generated_activation_token"])
d.Set(releaseVersion, raw["release_version"])
d.Set(authorizedActions, raw["authorized_actions"])
return nil
}
func resourceWorkerRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
wkrs := workers.NewClient(md.client)
wrr, err := wkrs.Read(ctx, d.Id())
if err != nil {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound {
d.SetId("")
return nil
}
return diag.Errorf("error calling read worker: %v", err)
}
if wrr == nil {
return diag.Errorf("worker nil after read")
}
if err := setFromWorkerResponseMap(d, wrr.GetResponse().Map); err != nil {
return diag.FromErr(err)
}
return nil
}
func resourceWorkerCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
opts := []workers.Option{}
if v, ok := d.GetOk(NameKey); ok {
opts = append(opts, workers.WithName(v.(string)))
}
if v, ok := d.GetOk(DescriptionKey); ok {
opts = append(opts, workers.WithDescription(v.(string)))
}
var workerAuthToken string
if v, ok := d.GetOk(workerGeneratedAuthToken); ok {
workerAuthToken = v.(string)
}
wkr := workers.NewClient(md.client)
if len(workerAuthToken) > 0 {
wkrc, err := wkr.CreateWorkerLed(ctx, workerAuthToken, scopeId, opts...)
if err != nil {
return diag.Errorf("error creating worker: %v", err)
}
if wkrc == nil {
return diag.Errorf("worker nil after create")
}
if err := setFromWorkerResponseMap(d, wkrc.GetResponse().Map); err != nil {
return diag.FromErr(err)
}
} else {
wkrc, err := wkr.CreateControllerLed(ctx, scopeId, opts...)
if err != nil {
return diag.Errorf("error creating worker: %v", err)
}
if wkrc == nil {
return diag.Errorf("worker nil after create")
}
if err := setFromWorkerResponseMap(d, wkrc.GetResponse().Map); err != nil {
return diag.FromErr(err)
}
}
return nil
}
func resourceWorkerUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
wkr := workers.NewClient(md.client)
opts := []workers.Option{}
var name *string
if d.HasChange(NameKey) {
opts = append(opts, workers.DefaultName())
nameVal, ok := d.GetOk(NameKey)
if ok {
nameStr := nameVal.(string)
name = &nameStr
opts = append(opts, workers.WithName(nameStr))
}
}
var desc *string
if d.HasChange(DescriptionKey) {
opts = append(opts, workers.DefaultDescription())
descVal, ok := d.GetOk(DescriptionKey)
if ok {
descStr := descVal.(string)
desc = &descStr
opts = append(opts, workers.WithDescription(descStr))
}
}
var versionInt int
if versionVal, ok := d.GetOk(version); ok {
versionInt = versionVal.(int)
}
if len(opts) > 0 {
opts = append(opts, workers.WithAutomaticVersioning(true))
_, err := wkr.Update(ctx, d.Id(), uint32(versionInt), opts...)
if err != nil {
return diag.Errorf("error updating worker: %v", err)
}
}
if d.HasChange(NameKey) {
if err := d.Set(NameKey, name); err != nil {
return diag.FromErr(err)
}
}
if d.HasChange(DescriptionKey) {
if err := d.Set(DescriptionKey, desc); err != nil {
return diag.FromErr(err)
}
}
return nil
}
func resourceWorkerDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
wClient := workers.NewClient(md.client)
_, err := wClient.Delete(ctx, d.Id())
if err != nil {
return diag.Errorf("error deleting worker: %v", err)
}
return nil
}