Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static Credential Store #236

Merged
merged 12 commits into from
Jul 27, 2022
60 changes: 60 additions & 0 deletions docs/resources/credential_store_static.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_credential_store_static Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The static credential store resource allows you to configure a Boundary static credential store.
---

# boundary_credential_store_static (Resource)

The static credential store resource allows you to configure a Boundary static credential store.

## Example Usage

```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "global scope"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}

resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}

resource "boundary_credential_store_static" "example" {
name = "example_static_credential_store"
description = "My first sttatic credential store!"
scope_id = boundary_scope.project.id
}
```

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

### Required

- `scope_id` (String) The scope for this credential store.

### Optional

- `description` (String) The static credential store description.
- `name` (String) The static credential store name. Defaults to the resource name.

### Read-Only

- `id` (String) The ID of the static credential store.

## Import

Import is supported using the following syntax:

```shell
terraform import boundary_credential_store_static.example_static_credential_store <my-id>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import boundary_credential_store_static.example_static_credential_store <my-id>
20 changes: 20 additions & 0 deletions examples/resources/boundary_credential_store_static/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "global scope"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}

resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}

resource "boundary_credential_store_static" "example" {
name = "example_static_credential_store"
description = "My first sttatic credential store!"
scope_id = boundary_scope.project.id
}
3 changes: 2 additions & 1 deletion internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/hashicorp/go-secure-stdlib/pluginutil/v2"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-boundary/plugins/kms"
kms_plugin_assets "github.com/hashicorp/terraform-provider-boundary/plugins/kms"
)

func init() {
Expand Down Expand Up @@ -70,6 +70,7 @@ func New() *schema.Provider {
"boundary_auth_method_oidc": resourceAuthMethodOidc(),
"boundary_credential_library_vault": resourceCredentialLibraryVault(),
"boundary_credential_store_vault": resourceCredentialStoreVault(),
"boundary_credential_store_static": resourceCredentialStoreStatic(),
"boundary_managed_group": resourceManagedGroup(),
"boundary_group": resourceGroup(),
"boundary_host": resourceHost(),
Expand Down
176 changes: 176 additions & 0 deletions internal/provider/resource_credential_store_static.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package provider

import (
"context"
"net/http"

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

const staticCredentialStoreType = "static"

func resourceCredentialStoreStatic() *schema.Resource {
return &schema.Resource{
Description: "The static credential store resource allows you to configure a Boundary static credential store.",

CreateContext: resourceStaticCredentialStoreCreate,
ReadContext: resourceStaticCredentialStoreRead,
UpdateContext: resourceStaticCredentialStoreUpdate,
DeleteContext: resourceStaticCredentialStoreDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

Schema: map[string]*schema.Schema{
IDKey: {
Description: "The ID of the static credential store.",
Type: schema.TypeString,
Computed: true,
},
NameKey: {
Description: "The static credential store name. Defaults to the resource name.",
Type: schema.TypeString,
Optional: true,
},
DescriptionKey: {
Description: "The static credential store description.",
Type: schema.TypeString,
Optional: true,
},
ScopeIdKey: {
Description: "The scope for this credential store.",
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
},
}
}

func setFromStaticCredentialStoreResponseMap(d *schema.ResourceData, raw map[string]interface{}, fromRead bool) error {
if err := d.Set(NameKey, raw[NameKey]); err != nil {
return err
}
if err := d.Set(DescriptionKey, raw[DescriptionKey]); err != nil {
return err
}
if err := d.Set(ScopeIdKey, raw[ScopeIdKey]); err != nil {
return err
}

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

return nil
}

func resourceStaticCredentialStoreCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)

var opts []credentialstores.Option
if v, ok := d.GetOk(NameKey); ok {
opts = append(opts, credentialstores.WithName(v.(string)))
}
if v, ok := d.GetOk(DescriptionKey); ok {
opts = append(opts, credentialstores.WithDescription(v.(string)))
}

var scope string
gotScope, ok := d.GetOk(ScopeIdKey)
if ok {
scope = gotScope.(string)
} else {
return diag.Errorf("no scope is set")
}

client := credentialstores.NewClient(md.client)
cr, err := client.Create(ctx, staticCredentialStoreType, scope, opts...)
if err != nil {
return diag.Errorf("error creating credential store: %v", err)
}
if cr == nil {
return diag.Errorf("nil credential store after create")
}

if err := setFromStaticCredentialStoreResponseMap(d, cr.GetResponse().Map, false); err != nil {
return diag.Errorf("error generating credential store from response map: %v", err)
}

return nil
}

func resourceStaticCredentialStoreRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
client := credentialstores.NewClient(md.client)

cr, err := client.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 reading credential store: %v", err)
}
if cr == nil {
return diag.Errorf("credential store nil after read")
}

if err := setFromStaticCredentialStoreResponseMap(d, cr.GetResponse().Map, true); err != nil {
return diag.Errorf("error generating credential store from response map: %v", err)
}

return nil
}

func resourceStaticCredentialStoreUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
client := credentialstores.NewClient(md.client)

var opts []credentialstores.Option
if d.HasChange(NameKey) {
opts = append(opts, credentialstores.DefaultName())
nameVal, ok := d.GetOk(NameKey)
if ok {
opts = append(opts, credentialstores.WithName(nameVal.(string)))
}
}

if d.HasChange(DescriptionKey) {
opts = append(opts, credentialstores.DefaultDescription())
descVal, ok := d.GetOk(DescriptionKey)
if ok {
opts = append(opts, credentialstores.WithDescription(descVal.(string)))
}
}

if len(opts) > 0 {
opts = append(opts, credentialstores.WithAutomaticVersioning(true))
crUpdate, err := client.Update(ctx, d.Id(), 0, opts...)
if err != nil {
return diag.Errorf("error updating credential store: %v", err)
}
if crUpdate == nil {
return diag.Errorf("credential store nil after update")
}

if err = setFromStaticCredentialStoreResponseMap(d, crUpdate.GetResponse().Map, false); err != nil {
return diag.Errorf("error generating credential store from response map: %v", err)
}
}

return nil
}

func resourceStaticCredentialStoreDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
client := credentialstores.NewClient(md.client)

_, err := client.Delete(ctx, d.Id())
if err != nil {
return diag.Errorf("error deleting credential store: %v", err)
}

return nil
}
Loading