generated from hashicorp/terraform-provider-scaffolding
-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(policy): support storage policies within terraform
- Loading branch information
Showing
6 changed files
with
630 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,25 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "boundary_policy_attachment Resource - terraform-provider-boundary" | ||
subcategory: "" | ||
description: |- | ||
--- | ||
|
||
# boundary_policy_attachment (Resource) | ||
|
||
|
||
|
||
|
||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- `policy_id` (String) | ||
- `scope_id` (String) | ||
|
||
### Read-Only | ||
|
||
- `id` (String) The ID of this resource. |
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,33 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "boundary_storage_policy Resource - terraform-provider-boundary" | ||
subcategory: "" | ||
description: |- | ||
The storage policy resource allows you to configure a Boundary storage policy. Storage policies allow an admin to configure how long session recordings must be stored and when to delete them. Storage policies must be applied to the global scope or an org scope in order to take effect. | ||
--- | ||
|
||
# boundary_storage_policy (Resource) | ||
|
||
The storage policy resource allows you to configure a Boundary storage policy. Storage policies allow an admin to configure how long session recordings must be stored and when to delete them. Storage policies must be applied to the global scope or an org scope in order to take effect. | ||
|
||
|
||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- `scope_id` (String) The scope for this policy. | ||
|
||
### Optional | ||
|
||
- `delete_after_days` (Number) The number of days after which a session recording will be automatically deleted. Defaults to 0: never automatically delete. However, delete_after_days and retain_for_days cannot both be 0. | ||
- `delete_after_overridable` (Boolean) Whether or not the associated delete_after_days value can be overridden by org scopes. Note: if the associated delete_after_days value is 0, overridable is ignored | ||
- `description` (String) The policy description. | ||
- `name` (String) The policy name. Defaults to the resource name. | ||
- `retain_for_days` (Number) The number of days a session recording is required to be stored. Defaults to 0: allow deletions at any time. However, retain_for_days and delete_after_days cannot both be 0. | ||
- `retain_for_overridable` (Boolean) Whether or not the associated retain_for_days value can be overridden by org scopes. Note: if the associated retain_for_days value is 0, overridable is ignored. | ||
|
||
### Read-Only | ||
|
||
- `id` (String) The ID of the policy. |
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,27 @@ | ||
resource "boundary_scope" "global" { | ||
global_scope = true | ||
scope_id = "global" | ||
} | ||
|
||
resource "boundary_scope" "org" { | ||
name = "organization_one" | ||
description = "My first scope!" | ||
scope_id = boundary_scope.global.id | ||
auto_create_admin_role = true | ||
auto_create_default_role = true | ||
} | ||
|
||
resource "boundary_storage_policy" "foo" { | ||
name = "foo" | ||
description = "Foo policy" | ||
scope_id = boundary_scope.org.id | ||
retain_for_days = 10 | ||
retain_for_overridable = false | ||
delete_after_days = 10 | ||
delete_after_overridable = true | ||
} | ||
|
||
resource "boundary_policy_attachment" "foo_attachment" { | ||
scope_id = boundary_scope.org.id | ||
policy_id = boundary_storage_policy.foo.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
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,167 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package provider | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/hashicorp/boundary/api" | ||
"github.com/hashicorp/boundary/api/scopes" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
const ( | ||
policyPolicyIdKey = "policy_id" | ||
policyStoragePolicyPrefix = "pst_" | ||
) | ||
|
||
func resourcePolicyAttachment() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateContext: resourcePolicyAttachmentCreate, | ||
ReadWithoutTimeout: resourcePolicyAttachmentRead, | ||
DeleteWithoutTimeout: resourcePolicyAttachmentDelete, | ||
|
||
Importer: &schema.ResourceImporter{ | ||
StateContext: schema.ImportStatePassthroughContext, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
ScopeIdKey: { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
policyPolicyIdKey: { | ||
Type: schema.TypeString, | ||
ForceNew: true, | ||
Required: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourcePolicyAttachmentCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
md := meta.(*metaData) | ||
scp := scopes.NewClient(md.client) | ||
opts := []scopes.Option{scopes.WithAutomaticVersioning(true)} | ||
|
||
var scopeId string | ||
if scopeIdVal, ok := d.GetOk(ScopeIdKey); ok { | ||
scopeId = scopeIdVal.(string) | ||
} else { | ||
return diag.Errorf("no scope ID provided") | ||
} | ||
|
||
if err := d.Set(ScopeIdKey, scopeId); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
var policyId string | ||
if policyIdVal, ok := d.GetOk(policyPolicyIdKey); ok { | ||
policyId = policyIdVal.(string) | ||
} else { | ||
return diag.Errorf("no policy ID provided") | ||
} | ||
|
||
// other policy types may be added here and in other switches with this file | ||
var policyType string | ||
switch { | ||
case strings.HasPrefix(policyId, policyStoragePolicyPrefix): | ||
if _, err := scp.AttachStoragePolicy(ctx, scopeId, 0, policyId, opts...); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
policyType = policyTypeStorage | ||
default: | ||
return diag.Errorf("unknown policy type provided.") | ||
} | ||
|
||
if err := d.Set(policyPolicyIdKey, policyId); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
// scopes can have one and only one policy of each type | ||
d.SetId(fmt.Sprintf("%s_policy:%s", policyType, scopeId)) | ||
|
||
return nil | ||
} | ||
|
||
func resourcePolicyAttachmentRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
md := meta.(*metaData) | ||
scp := scopes.NewClient(md.client) | ||
|
||
var scopeId string | ||
if scopeIdVal, ok := d.GetOk(ScopeIdKey); ok { | ||
scopeId = scopeIdVal.(string) | ||
} else { | ||
return diag.Errorf("no scope ID provided") | ||
} | ||
|
||
var policyId string | ||
if policyIdVal, ok := d.GetOk(policyPolicyIdKey); ok { | ||
policyId = policyIdVal.(string) | ||
} else { | ||
return diag.Errorf("no policy ID provided") | ||
} | ||
|
||
s, err := scp.Read(ctx, scopeId) | ||
if err != nil { | ||
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { | ||
// the scope is gone, destroy this resource | ||
d.SetId("") | ||
return nil | ||
} | ||
return diag.Errorf("error reading scope: %v", err) | ||
} | ||
if s == nil { | ||
return diag.Errorf("scope nil after read") | ||
} | ||
|
||
switch { | ||
case strings.HasPrefix(policyId, policyStoragePolicyPrefix): | ||
if policyId != s.GetItem().StoragePolicyId { | ||
// this policy is no longer attached to the scope, destroy this resource | ||
d.SetId("") | ||
return nil | ||
} | ||
default: | ||
return diag.Errorf("unknown policy type provided.") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourcePolicyAttachmentDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
md := meta.(*metaData) | ||
scp := scopes.NewClient(md.client) | ||
opts := []scopes.Option{scopes.WithAutomaticVersioning(true)} | ||
|
||
var scopeId string | ||
if scopeIdVal, ok := d.GetOk(ScopeIdKey); ok { | ||
scopeId = scopeIdVal.(string) | ||
} else { | ||
return diag.Errorf("no scope ID provided") | ||
} | ||
|
||
var policyId string | ||
if policyIdVal, ok := d.GetOk(policyPolicyIdKey); ok { | ||
policyId = policyIdVal.(string) | ||
} else { | ||
return diag.Errorf("no policy ID provided") | ||
} | ||
|
||
switch { | ||
case strings.HasPrefix(policyId, policyStoragePolicyPrefix): | ||
if _, err := scp.DetachStoragePolicy(ctx, scopeId, 0, opts...); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
default: | ||
return diag.Errorf("unknown policy type provided.") | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.