Skip to content

Commit

Permalink
Merge pull request #19 from aeber/add_vault_credential
Browse files Browse the repository at this point in the history
Add vault credential resource
  • Loading branch information
josh-silvas authored Nov 7, 2024
2 parents 232e575 + 3756922 commit 74da97d
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 1 deletion.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.1.7
v1.2.0
44 changes: 44 additions & 0 deletions docs/resources/credential_vault.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "awx_credential_vault Resource - terraform-provider-awx"
subcategory: ""
description: |-
awx_credential_vault manages vault credentials in AWX.
---

# awx_credential_vault (Resource)

`awx_credential_vault` manages vault credentials in AWX.

## Example Usage

```terraform
resource "awx_organization" "example" {
name = "example"
}
resource "awx_credential_vault" "example" {
name = "vault-credential"
organization_id = awx_organization.example.id
description = "This is a vault credential"
vault_password = "password"
}
```

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

### Required

- `name` (String) The name of the credential.
- `vault_password` (String, Sensitive) Vault Password.

### Optional

- `description` (String) The description of the credential.
- `organization_id` (Number) The organization ID this credential belongs to.
- `vault_id` (String) The vault identity to use.

### Read-Only

- `id` (String) The ID of this resource.
10 changes: 10 additions & 0 deletions examples/resources/awx_credential_vault/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resource "awx_organization" "example" {
name = "example"
}

resource "awx_credential_vault" "example" {
name = "vault-credential"
organization_id = awx_organization.example.id
description = "This is a vault credential"
vault_password = "password"
}
1 change: 1 addition & 0 deletions internal/awx/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func Provider() *schema.Provider { //nolint:funlen
"awx_credential_scm": resourceCredentialSCM(),
"awx_credential_gitlab": resourceCredentialGitlab(),
"awx_credential_galaxy": resourceCredentialGalaxy(),
"awx_credential_vault": resourceCredentialVault(),
"awx_execution_environment": resourceExecutionEnvironment(),
"awx_host": resourceHost(),
"awx_instance_group": resourceInstanceGroup(),
Expand Down
179 changes: 179 additions & 0 deletions internal/awx/resource_credential_vault.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package awx

import (
"context"
"fmt"
"strconv"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
awx "github.com/josh-silvas/terraform-provider-awx/tools/goawx"
)

const vaultCredentialTypeName = "Vault" //nolint:gosec

func resourceCredentialVault() *schema.Resource {
return &schema.Resource{
Description: "`awx_credential_vault` manages vault credentials in AWX.",
CreateContext: resourceCredentialVaultCreate,
ReadContext: resourceCredentialVaultRead,
UpdateContext: resourceCredentialVaultUpdate,
DeleteContext: resourceCredentialDelete,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "The name of the credential.",
},
"description": {
Type: schema.TypeString,
Optional: true,
Description: "The description of the credential.",
},
"organization_id": {
Type: schema.TypeInt,
Optional: true,
Description: "The organization ID this credential belongs to.",
},
"vault_password": {
Type: schema.TypeString,
Required: true,
Sensitive: true,
Description: "Vault Password.",
},
"vault_id": {
Type: schema.TypeString,
Optional: true,
Description: "The vault identity to use.",
},
},
}
}

func resourceCredentialVaultCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
var err error

client := m.(*awx.AWX)
vaultCredType, err := client.CredentialTypeService.GetCredentialTypeByName(vaultCredentialTypeName, map[string]string{})
if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Unable to create new credentials",
Detail: fmt.Sprintf("Unable to fetch credential type with Name: %s. Error: %s", vaultCredentialTypeName, err.Error()),
})
return diags
}

newCredential := map[string]interface{}{
"name": d.Get("name").(string),
"description": d.Get("description").(string),
"organization": d.Get("organization_id").(int),
"credential_type": vaultCredType.ID,
"inputs": map[string]interface{}{
"vault_password": d.Get("vault_password").(string),
"vault_id": d.Get("vault_id").(string),
},
}

cred, err := client.CredentialsService.CreateCredentials(newCredential, map[string]string{})
if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Unable to create new credentials",
Detail: fmt.Sprintf("Unable to create new credentials: %s", err.Error()),
})
return diags
}

d.SetId(strconv.Itoa(cred.ID))
resourceCredentialVaultRead(ctx, d, m)

return diags
}

func resourceCredentialVaultRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics

client := m.(*awx.AWX)
id, _ := strconv.Atoi(d.Id())
cred, err := client.CredentialsService.GetCredentialsByID(id, map[string]string{})
if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Unable to fetch credentials",
Detail: fmt.Sprintf("Unable to fetch credentials with id %d: %s", id, err.Error()),
})
return diags
}

if err := d.Set("name", cred.Name); err != nil {
return diag.FromErr(err)
}
if err := d.Set("description", cred.Description); err != nil {
return diag.FromErr(err)
}
if err := d.Set("organization_id", cred.OrganizationID); err != nil {
return diag.FromErr(err)
}
if err := d.Set("vault_password", cred.Inputs["vault_password"]); err != nil {
return diag.FromErr(err)
}
if err := d.Set("vault_id", cred.Inputs["vault_id"]); err != nil {
return diag.FromErr(err)
}

return diags
}

func resourceCredentialVaultUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics

keys := []string{
"name",
"description",
"organization_id",
"vault_password",
"vault_id",
}

client := m.(*awx.AWX)

if d.HasChanges(keys...) {
var err error

vaultCredType, err := client.CredentialTypeService.GetCredentialTypeByName(vaultCredentialTypeName, map[string]string{})
if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Unable to create new credentials",
Detail: fmt.Sprintf("Unable to fetch credential type with Name: %s. Error: %s", vaultCredentialTypeName, err.Error()),
})
return diags
}

id, _ := strconv.Atoi(d.Id())
updatedCredential := map[string]interface{}{
"name": d.Get("name").(string),
"description": d.Get("description").(string),
"organization": d.Get("organization_id").(int),
"credential_type": vaultCredType.ID,
"inputs": map[string]interface{}{
"vault_password": d.Get("vault_password").(string),
"vault_id": d.Get("vault_id").(string),
},
}

_, err = client.CredentialsService.UpdateCredentialsByID(id, updatedCredential, map[string]string{})
if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Unable to update existing credentials",
Detail: fmt.Sprintf("Unable to update existing credentials with id %d: %s", id, err.Error()),
})
return diags
}
}

return resourceCredentialVaultRead(ctx, d, m)
}

0 comments on commit 74da97d

Please sign in to comment.