-
Notifications
You must be signed in to change notification settings - Fork 554
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding new resource for password policy
* https://www.vaultproject.io/docs/concepts/password-policies Co-authored-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com>
- Loading branch information
1 parent
e0161ec
commit c3b3c8a
Showing
5 changed files
with
297 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,109 @@ | ||
package vault | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"log" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
"github.com/hashicorp/vault/api" | ||
) | ||
|
||
func readPasswordPolicy(client *api.Client, name string) (map[string]interface{}, error) { | ||
r := client.NewRequest("GET", fmt.Sprintf("/v1/sys/policies/password/%s", name)) | ||
|
||
ctx, cancelFunc := context.WithCancel(context.Background()) | ||
defer cancelFunc() | ||
resp, err := client.RawRequestWithContext(ctx, r) | ||
if resp != nil { | ||
defer resp.Body.Close() | ||
if resp.StatusCode == 404 { | ||
return nil, nil | ||
} | ||
} | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
secret, err := api.ParseSecret(resp.Body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if secret == nil || secret.Data == nil { | ||
return nil, errors.New("data from server response is empty") | ||
} | ||
return secret.Data, nil | ||
} | ||
|
||
func passwordPolicyDelete(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*api.Client) | ||
|
||
name := d.Id() | ||
|
||
log.Printf("[DEBUG] Deleting %s password policy from Vault", name) | ||
|
||
r := client.NewRequest("DELETE", fmt.Sprintf("/v1/sys/policies/password/%s", name)) | ||
|
||
ctx, cancelFunc := context.WithCancel(context.Background()) | ||
defer cancelFunc() | ||
resp, err := client.RawRequestWithContext(ctx, r) | ||
if err == nil { | ||
defer resp.Body.Close() | ||
} | ||
|
||
return err | ||
} | ||
|
||
func passwordPolicyRead(attributes []string, d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*api.Client) | ||
|
||
name := d.Id() | ||
|
||
policy, err := readPasswordPolicy(client, name) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error reading from Vault: %s", err) | ||
} | ||
|
||
for _, value := range attributes { | ||
d.Set(value, policy[value]) | ||
} | ||
d.Set("name", name) | ||
|
||
return nil | ||
} | ||
|
||
func passwordPolicyWrite(attributes []string, d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*api.Client) | ||
|
||
name := d.Get("name").(string) | ||
|
||
log.Printf("[DEBUG] Writing %s password policy to Vault", name) | ||
|
||
body := map[string]interface{}{} | ||
for _, value := range attributes { | ||
body[value] = d.Get(value) | ||
} | ||
|
||
r := client.NewRequest("PUT", fmt.Sprintf("/v1/sys/policies/password/%s", name)) | ||
if err := r.SetJSONBody(body); err != nil { | ||
return err | ||
} | ||
|
||
ctx, cancelFunc := context.WithCancel(context.Background()) | ||
defer cancelFunc() | ||
resp, err := client.RawRequestWithContext(ctx, r) | ||
if err != nil { | ||
return err | ||
} | ||
defer resp.Body.Close() | ||
|
||
if err != nil { | ||
return fmt.Errorf("error writing to Vault: %s", err) | ||
} | ||
|
||
d.SetId(name) | ||
|
||
return passwordPolicyRead(attributes, d, meta) | ||
} |
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,47 @@ | ||
package vault | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
) | ||
|
||
var passwordPolicyAttributes = []string{"policy"} | ||
|
||
func passwordPolicyResource() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourcePasswordPolicyWrite, | ||
Update: resourcePasswordPolicyWrite, | ||
Delete: resourcePasswordPolicyDelete, | ||
Read: resourcePasswordPolicyRead, | ||
|
||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
Description: "Name of the password policy.", | ||
}, | ||
|
||
"policy": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "The password policy document", | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourcePasswordPolicyWrite(d *schema.ResourceData, meta interface{}) error { | ||
return passwordPolicyWrite(passwordPolicyAttributes, d, meta) | ||
} | ||
|
||
func resourcePasswordPolicyDelete(d *schema.ResourceData, meta interface{}) error { | ||
return passwordPolicyDelete(d, meta) | ||
} | ||
|
||
func resourcePasswordPolicyRead(d *schema.ResourceData, meta interface{}) error { | ||
return passwordPolicyRead(passwordPolicyAttributes, d, meta) | ||
} |
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,89 @@ | ||
package vault | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/terraform" | ||
"github.com/hashicorp/vault/api" | ||
) | ||
|
||
func TestAccPasswordPolicy(t *testing.T) { | ||
|
||
policyName := acctest.RandomWithPrefix("test-policy") | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testProviders, | ||
CheckDestroy: testAccPasswordPolicyCheckDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccPasswordPolicy(policyName, "length = 20\nrule \"charset\" {\n charset = \"abcde\"\n}\n"), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr("vault_password_policy.test", "name", policyName), | ||
resource.TestCheckResourceAttrSet("vault_password_policy.test", "policy"), | ||
), | ||
}, | ||
{ | ||
Config: testAccPasswordPolicy(policyName, "length = 20\nrule \"charset\" {\n charset = \"abcde\"\n}\nrule \"charset\" {\n charset = \"1234567890\"\nmin-chars = 1\n}\n"), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr("vault_password_policy.test", "name", policyName), | ||
resource.TestCheckResourceAttrSet("vault_password_policy.test", "policy"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccPasswordPolicy_import(t *testing.T) { | ||
policyName := acctest.RandomWithPrefix("test-policy") | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testProviders, | ||
CheckDestroy: testAccPasswordPolicyCheckDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccPasswordPolicy(policyName, "length = 20\nrule \"charset\" {\n charset = \"abcde\"\n}\n"), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr("vault_password_policy.test", "name", policyName), | ||
resource.TestCheckResourceAttrSet("vault_password_policy.test", "policy"), | ||
), | ||
}, | ||
{ | ||
ResourceName: "vault_password_policy.test", | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccPasswordPolicyCheckDestroy(s *terraform.State) error { | ||
client := testProvider.Meta().(*api.Client) | ||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "vault_password_policy" { | ||
continue | ||
} | ||
name := rs.Primary.Attributes["name"] | ||
data, err := client.Logical().Read(fmt.Sprintf("sys/policies/password/%s", name)) | ||
if err != nil { | ||
return err | ||
} | ||
if data != nil { | ||
return fmt.Errorf("Password policy %s still exists", name) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func testAccPasswordPolicy(policyName string, policy string) string { | ||
return fmt.Sprintf(` | ||
resource "vault_password_policy" "test" { | ||
name = "%s" | ||
policy = <<EOT | ||
%s | ||
EOT | ||
}`, policyName, 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,48 @@ | ||
--- | ||
layout: "vault" | ||
page_title: "Vault: vault_password_policy resource" | ||
sidebar_current: "docs-vault-resource-password-policy" | ||
description: |- | ||
Writes Password policies for Vault | ||
--- | ||
|
||
# vault\_password\_policy | ||
|
||
Provides a resource to manage Password Policies | ||
|
||
**Note** this feature is available only Vault 1.5+ | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
resource "vault_password_policy" "alphanumeric" { | ||
name = "alphanumeric" | ||
policy = <<EOT | ||
length = 20 | ||
rule "charset" { | ||
charset = "abcdefghijklmnopqrstuvwxyz0123456789" | ||
} | ||
EOT | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `name` - (Required) The name of the password policy. | ||
|
||
* `policy` - (Required) String containing a password policy. | ||
|
||
## Attributes Reference | ||
|
||
No additional attributes are exported by this resource. | ||
|
||
## Import | ||
|
||
Password policies can be imported using the `name`, e.g. | ||
|
||
``` | ||
$ terraform import vault_password_policy.alphanumeric alphanumeric | ||
``` |