Skip to content

Commit

Permalink
feat(str): add resource for encrypting a string
Browse files Browse the repository at this point in the history
  • Loading branch information
Clément Decoodt committed Aug 21, 2023
1 parent 9e2c80a commit d5072d2
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 0 deletions.
19 changes: 19 additions & 0 deletions docs/resources/ansiblevault_enc_string.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# `ansiblevault_enc_string` Resource

Use `ansiblevault_enc_string` resource to encrypt `value` using the provided ansible_vault key into `encrypted`

## Example Usage

See [examples](https://github.com/MeilleursAgents/terraform-provider-ansiblevault/tree/master/examples) directory

## Argument Reference

The following arguments are supported:

* `value` - (Required) the raw secret as string.

## Attributes Reference

The following attributes are exported:

* `encrypted` - the ansible vault secret.
8 changes: 8 additions & 0 deletions examples/terraform/provider_pass.tf
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ EOF
key = "API_KEY"
}

resource "ansiblevault_enc_string" "key_enc_string" {
value = "THIS_WAS_IN_CLEAR_TEXT"
}

output "path" {
value = data.ansiblevault_path.path.value
}
Expand All @@ -42,3 +46,7 @@ output "env" {
output "key_string" {
value = data.ansiblevault_string.key_string.value
}

output "key_enc_string" {
value = ansiblevault_enc_string.key_enc_string.encrypted
}
57 changes: 57 additions & 0 deletions pkg/provider/in_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,27 @@ func inStringResource() *schema.Resource {
}
}

func inStringEncResource() *schema.Resource {
return &schema.Resource{
Read: inStringEncRead,
Create: inStringEncRead,
Delete: inStringEncDelete,
Schema: map[string]*schema.Schema{
"value": {
Required: true,
ForceNew: true,
Description: "Vault value found",
Type: schema.TypeString,
},
"encrypted": {
Computed: true,
Type: schema.TypeString,
Description: "Ansible-vault string representation",
},
},
}
}

func inStringRead(data *schema.ResourceData, m interface{}) error {
raw := data.Get("encrypted").(string)
key := data.Get("key").(string)
Expand All @@ -50,3 +71,39 @@ func inStringRead(data *schema.ResourceData, m interface{}) error {

return nil
}

func inStringEncRead(data *schema.ResourceData, m interface{}) error {
value := data.Get("value").(string)
enc := data.Get("encrypted").(string)

if len(enc) != 0 {
dec, err := m.(*vault.App).InString(enc, "")
// If there is an error, we need to update it
if err == nil {
if dec == value {
return nil
}
}
}

data.SetId(time.Now().UTC().String())

encrypted, err := m.(*vault.App).InEncString(value)

if err != nil {
data.SetId("")
return err
}

if err := data.Set("encrypted", encrypted); err != nil {
data.SetId("")
return err
}

return nil
}

func inStringEncDelete(d *schema.ResourceData, m interface{}) error {
d.SetId("")
return nil
}
55 changes: 55 additions & 0 deletions pkg/provider/in_string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/MeilleursAgents/terraform-provider-ansiblevault/v2/pkg/vault"
ansible_vault "github.com/sosedoff/ansible-vault-go"
)

func TestInStringRead(t *testing.T) {
Expand Down Expand Up @@ -92,3 +93,57 @@ func TestInStringRead(t *testing.T) {
})
}
}

func TestInStringEncRead(t *testing.T) {
var cases = []struct {
intention string
input string
wantErr error
}{
{
"simple",
"PROD_KEEP_IT_SECRET",
nil,
},
}

for _, testCase := range cases {
t.Run(testCase.intention, func(t *testing.T) {
data := inStringResource().Data(nil)

if err := data.Set("value", testCase.input); err != nil {
t.Errorf("unable to set raw value: %s", err)
return
}

vaultApp, err := vault.New("secret", ansibleFolder)
if err != nil {
t.Errorf("unable to create vault app: %#v", err)
return
}

err = inStringEncRead(data, vaultApp)
result := data.Get("encrypted").(string)

failed := false

if err == nil && testCase.wantErr != nil {
failed = true
} else if err != nil && testCase.wantErr == nil {
failed = true
} else if err != nil && err.Error() != testCase.wantErr.Error() {
failed = true
} else {
decValue, err := ansible_vault.Decrypt(result, "secret")
if err != nil || decValue != testCase.input {
t.Errorf("inStringEncRead() = (`%s`, %#v), want (`%s`, %#v)", result, err, decValue, testCase.wantErr)
failed = true
}
}

if failed {
t.Errorf("inStringEncRead() = (`%s`, %#v), want (%#v)", result, err, testCase.wantErr)
}
})
}
}
3 changes: 3 additions & 0 deletions pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ func Provider() *schema.Provider {
"ansiblevault_path": inPathResource(),
"ansiblevault_string": inStringResource(),
},
ResourcesMap: map[string]*schema.Resource{
"ansiblevault_enc_string": inStringEncResource(),
},
ConfigureFunc: func(r *schema.ResourceData) (interface{}, error) {
return configure(r.Get("vault_path").(string), r.Get("vault_pass").(string), r.Get("root_folder").(string))
},
Expand Down
5 changes: 5 additions & 0 deletions pkg/vault/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,8 @@ func (a App) InPath(vaultPath string, key string) (string, error) {
func (a App) InString(rawVault string, key string) (string, error) {
return a.getVaultKey(rawVault, key, ansible_vault.Decrypt)
}

// InString encrypts a string
func (a App) InEncString(rawValue string) (string, error) {
return ansible_vault.Encrypt(rawValue, a.vaultPassword)
}

0 comments on commit d5072d2

Please sign in to comment.