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

Add acceptance tests for the password policy framework implementation #2113

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions internal/framework/base/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,24 @@ import (
)

// BaseModel describes common fields for all of the Terraform resource data models
//
// Ideally this struct would be imbedded into all Resources and DataSources.
// However, the Terraform Plugin Framework doesn't support unmarshalling nested
// structs. See https://github.com/hashicorp/terraform-plugin-framework/issues/242
// So for now, we must duplicate all fields.
Comment on lines +17 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the context here.

type BaseModel struct {
ID types.String `tfsdk:"id"`
Namespace types.String `tfsdk:"namespace"`
}

func baseSchema() map[string]schema.Attribute {
return map[string]schema.Attribute{
// Required for acceptance testing
// https://developer.hashicorp.com/terraform/plugin/framework/acctests#no-id-found-in-attributes
"id": schema.StringAttribute{
Computed: true,
MarkdownDescription: "ID required by the testing framework",
},
consts.FieldNamespace: schema.StringAttribute{
Optional: true,
PlanModifiers: []planmodifier.String{
Expand Down
4 changes: 2 additions & 2 deletions internal/provider/fwprovider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/schema/validator"

"github.com/hashicorp/terraform-provider-vault/internal/consts"
"github.com/hashicorp/terraform-provider-vault/internal/sys"
"github.com/hashicorp/terraform-provider-vault/internal/vault/sys"
)

// Ensure the implementation satisfies the provider.Provider interface
Expand Down Expand Up @@ -47,7 +47,7 @@ func (p *fwprovider) Metadata(ctx context.Context, req provider.MetadataRequest,
//
// Schema is called during validate, plan and apply.
func (p *fwprovider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
// TODO(JM): This schema must match exactly to the SDKv2 provider's schema
// This schema must match exactly to the SDKv2 provider's schema
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
// Not `Required` but must be set via config or env. Otherwise we
Expand Down
40 changes: 40 additions & 0 deletions internal/providertest/providertest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package providertest

import (
"context"

"github.com/hashicorp/terraform-plugin-go/tfprotov5"
"github.com/hashicorp/terraform-provider-vault/vault"
)

// ProtoV5ProviderFactories is a static map containing only the main provider instance
var (
ProtoV5ProviderFactories map[string]func() (tfprotov5.ProviderServer, error) = protoV5ProviderFactoriesInit(context.Background(), "vault")
)

// testAccProtoV5ProviderFactories will return a map of provider servers
// suitable for use as a resource.TestStep.ProtoV5ProviderFactories.
//
// When multiplexing providers, the schema and configuration handling must
// exactly match between all underlying providers of the mux server. Mismatched
// schemas will result in a runtime error.
// see: https://developer.hashicorp.com/terraform/plugin/framework/migrating/mux
//
// Any tests that use this function will serve as a smoketest to verify the
// provider schemas match 1-1 so that we may catch runtime errors.
func protoV5ProviderFactoriesInit(ctx context.Context, providerNames ...string) map[string]func() (tfprotov5.ProviderServer, error) {
factories := make(map[string]func() (tfprotov5.ProviderServer, error), len(providerNames))

for _, name := range providerNames {
factories[name] = func() (tfprotov5.ProviderServer, error) {
providerServerFactory, _, err := vault.ProtoV5ProviderServerFactory(ctx)
if err != nil {
return nil, err
}

return providerServerFactory(), nil
}
}

return factories
}
3 changes: 3 additions & 0 deletions internal/vault/auth/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Vault Auth Methods

This package contains Vault [auth method API](https://developer.hashicorp.com/vault/api-docs/auth) resources and datasources.
3 changes: 3 additions & 0 deletions internal/vault/secrets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Vault Secrets Engine

This package contains Vault [secrets engine API](https://developer.hashicorp.com/vault/api-docs/secret) resources and datasources.
3 changes: 3 additions & 0 deletions internal/vault/sys/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Vault System Backend

This package contains Vault [system backend API](https://developer.hashicorp.com/vault/api-docs/system) resources and datasources.
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ type PasswordPolicyResource struct {
}

func (r *PasswordPolicyResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_password_policy_fw"
resp.TypeName = req.ProviderTypeName + "_password_policy"
}

// PasswordPolicyModel describes the Terraform resource data model to match the
// resource schema.
type PasswordPolicyModel struct {
// common fields to all resources
ID types.String `tfsdk:"id"`
Namespace types.String `tfsdk:"namespace"`

// fields specific to this resource
Name types.String `tfsdk:"name"`
Policy types.String `tfsdk:"policy"`
}
Expand Down Expand Up @@ -109,6 +112,9 @@ func (r *PasswordPolicyResource) Create(ctx context.Context, req resource.Create
return
}

// write the ID to state which is required for acceptance testing
plan.ID = types.StringValue(path)

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}
Expand Down Expand Up @@ -177,6 +183,9 @@ func (r *PasswordPolicyResource) Read(ctx context.Context, req resource.ReadRequ

state.Policy = types.StringValue(readResp.Policy)

// write the ID to state which is required for acceptance testing
state.ID = types.StringValue(path)

resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}

Expand Down Expand Up @@ -213,6 +222,9 @@ func (r *PasswordPolicyResource) Update(ctx context.Context, req resource.Update
return
}

// write the ID to state which is required for acceptance testing
plan.ID = types.StringValue(path)

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}
Expand Down
49 changes: 49 additions & 0 deletions internal/vault/sys/password_policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package sys_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-provider-vault/internal/providertest"
"github.com/hashicorp/terraform-provider-vault/testutil"
)

func TestAccPasswordPolicy(t *testing.T) {
policyName := acctest.RandomWithPrefix("test-policy")
resourceName := "vault_password_policy.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testutil.TestAccPreCheck(t) },
ProtoV5ProviderFactories: providertest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccPasswordPolicyConfig(policyName, "length = 20\nrule \"charset\" {\n charset = \"abcde\"\n}\n"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", policyName),
resource.TestCheckResourceAttrSet(resourceName, "policy"),
),
},
{
Config: testAccPasswordPolicyConfig(policyName, "length = 20\nrule \"charset\" {\n charset = \"abcde\"\n}\nrule \"charset\" {\n charset = \"1234567890\"\nmin-chars = 1\n}\n"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", policyName),
resource.TestCheckResourceAttrSet(resourceName, "policy"),
),
},
},
})
}

func testAccPasswordPolicyConfig(policyName string, policy string) string {
return fmt.Sprintf(`
resource "vault_password_policy" "test" {
name = "%s"
policy = <<EOT
%s
EOT
}`, policyName, policy)
}
4 changes: 0 additions & 4 deletions vault/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,6 @@ var (
Resource: UpdateSchemaResource(rabbitMQSecretBackendRoleResource()),
PathInventory: []string{"/rabbitmq/roles/{name}"},
},
"vault_password_policy": {
Resource: UpdateSchemaResource(passwordPolicyResource()),
PathInventory: []string{"/sys/policy/password/{name}"},
},
"vault_pki_secret_backend_cert": {
Resource: UpdateSchemaResource(pkiSecretBackendCertResource()),
PathInventory: []string{"/pki/issue/{role}"},
Expand Down
52 changes: 0 additions & 52 deletions vault/resource_password_policy.go

This file was deleted.

98 changes: 0 additions & 98 deletions vault/resource_password_policy_test.go

This file was deleted.