generated from hashicorp/terraform-provider-scaffolding
-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for boundary_self_managed_worker resource. (#293)
* add initial prototype of self managed worker resource and associated tests * Add self managed worker resource and associated tests * Update internal/provider/resource_self_managed_worker.go Accept suggested schema changes for tags Co-authored-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com> * add environment variable check for worker led auth testing * change resource name from self_managed_worker to worker for consistency with the api * update tag schemas, ensure all attributes have descriptions * add generated docs for worker * add examples for worker resource * add examples for worker resource * remove merge conflict * Remove funtionality for reflecting tags in the schema * remove unused attributes (all tags) from schema, updates tests to use 'boundary_worker' on resource checks Co-authored-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
- Loading branch information
1 parent
7995149
commit cfc57d5
Showing
6 changed files
with
473 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "boundary_worker Resource - terraform-provider-boundary" | ||
subcategory: "" | ||
description: |- | ||
The resource allows you to create a self-managed worker object. | ||
--- | ||
|
||
# boundary_worker (Resource) | ||
|
||
The resource allows you to create a self-managed worker object. | ||
|
||
|
||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- `scope_id` (String) The scope for the worker. | ||
|
||
### Optional | ||
|
||
- `api_tags` (Map of List of String) API tags applied to the worker. | ||
- `description` (String) The description for the worker. | ||
- `name` (String) The name for the worker. | ||
- `worker_generated_auth_token` (String) 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. | ||
|
||
### Read-Only | ||
|
||
- `address` (String) The accessible address of the self managed worker. | ||
- `authorized_actions` (List of String) A list of actions that the worker is entitled to perform. | ||
- `canonical_tags` (Map of List of String) The aggregated view of worker tags and API tags. | ||
- `config_tags` (Map of List of String) Tags as configured in the worker's HCL file. | ||
- `controller_generated_activation_token` (String) A single use token generated by the controller to be passed to the self-managed worker. | ||
- `id` (String) The ID of the worker. | ||
- `release_version` (Number) The version of the Boundary binary running on the self managed worker. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
terraform import boundary_worker.foo <my-id> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
resource "boundary_worker" "controller_led" { | ||
scope_id = "global" | ||
name = "worker 1" | ||
description = "self managed worker with controlled led auth" | ||
worker_generated_auth_token = var.worker_generated_auth_token | ||
} | ||
|
||
resource "boundary_self_managed_worker" "worker_led" { | ||
scope_id = "global" | ||
name = "worker 2" | ||
description = "self managed worker with controlled led auth" | ||
worker_generated_auth_token = var.worker_generated_auth_token | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
package provider | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
|
||
"github.com/hashicorp/boundary/api" | ||
"github.com/hashicorp/boundary/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.", | ||
Type: schema.TypeString, | ||
Required: 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, | ||
}, | ||
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 Boundary 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(workerGeneratedAuthToken, raw["worker_generated_auth_token"]) | ||
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 | ||
} |
Oops, something went wrong.