Skip to content

Commit

Permalink
Merge branch 'hashicorp:main' into fix/vault_kv_secret_v2_cas
Browse files Browse the repository at this point in the history
  • Loading branch information
busser authored Jan 19, 2023
2 parents 445973c + 2f16cc5 commit f56e4b5
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 28 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ jobs:
with:
configuration-path: .github/labeler-pull-request-triage.yml
repo-token: "${{ secrets.GITHUB_TOKEN }}"
# See also: https://github.com/CodelyTV/pr-size-labeler/pull/26
- uses: bflad/pr-size-labeler@7df62b12a176513631973abfe151d2b6213c3f12
- uses: CodelyTV/pr-size-labeler@54ef36785e9f4cb5ecf1949cfc9b00dbb621d761 # v1.8.1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
xs_label: 'size/XS'
Expand Down
29 changes: 28 additions & 1 deletion internal/provider/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import (
"github.com/hashicorp/terraform-provider-vault/internal/consts"
)

const DefaultMaxHTTPRetries = 2
const (
DefaultMaxHTTPRetries = 2
enterpriseMetadata = "ent"
)

var (
MaxHTTPRetriesCCC int
Expand Down Expand Up @@ -101,6 +104,15 @@ func (p *ProviderMeta) IsAPISupported(minVersion *version.Version) bool {
return ver.GreaterThanOrEqual(minVersion)
}

// IsEnterpriseSupported returns a boolean
// describing whether the ProviderMeta
// vaultVersion supports enterprise
// features.
func (p *ProviderMeta) IsEnterpriseSupported() bool {
ver := p.GetVaultVersion()
return strings.Contains(ver.Metadata(), enterpriseMetadata)
}

// GetVaultVersion returns the providerMeta
// vaultVersion attribute.
func (p *ProviderMeta) GetVaultVersion() *version.Version {
Expand Down Expand Up @@ -337,6 +349,21 @@ func IsAPISupported(meta interface{}, minVersion *version.Version) bool {
return p.IsAPISupported(minVersion)
}

// IsEnterpriseSupported confirms that
// the providerMeta API supports enterprise
// features.
func IsEnterpriseSupported(meta interface{}) bool {
var p *ProviderMeta
switch v := meta.(type) {
case *ProviderMeta:
p = v
default:
panic(fmt.Sprintf("meta argument must be a %T, not %T", p, meta))
}

return p.IsEnterpriseSupported()
}

func getVaultVersion(client *api.Client) (*version.Version, error) {
resp, err := client.Sys().SealStatus()
if err != nil {
Expand Down
77 changes: 77 additions & 0 deletions internal/provider/meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,3 +444,80 @@ func TestIsAPISupported(t *testing.T) {
})
}
}

func TestIsEnterpriseSupported(t *testing.T) {
rootClient, err := api.NewClient(api.DefaultConfig())
if err != nil {
t.Fatalf("error initializing root client, err=%s", err)
}

VaultVersion10, err := version.NewVersion("1.10.0")
if err != nil {
t.Fatal(err)
}

VaultVersion11HSM, err := version.NewVersion("1.11.0+ent.hsm")
if err != nil {
t.Fatal(err)
}

VaultVersion12, err := version.NewVersion("1.12.0+ent")
if err != nil {
t.Fatal(err)
}

testCases := []struct {
name string
expected bool
meta interface{}
}{
{
name: "not-enterprise",
expected: false,
meta: &ProviderMeta{
client: rootClient,
vaultVersion: VaultVersion10,
},
},
{
name: "enterprise-hsm",
expected: true,
meta: &ProviderMeta{
client: rootClient,
vaultVersion: VaultVersion11HSM,
},
},
{
name: "enterprise",
expected: true,
meta: &ProviderMeta{
client: rootClient,
vaultVersion: VaultVersion12,
},
},
}

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
if tt.meta != nil {
m := tt.meta.(*ProviderMeta)
m.resourceData = schema.TestResourceDataRaw(t,
map[string]*schema.Schema{
consts.FieldNamespace: {
Type: schema.TypeString,
Required: true,
},
},
map[string]interface{}{},
)
tt.meta = m
}

isEnterprise := tt.meta.(*ProviderMeta).IsEnterpriseSupported()

if isEnterprise != tt.expected {
t.Errorf("IsEnterpriseSupported() got = %v, want %v", isEnterprise, tt.expected)
}
})
}
}
2 changes: 2 additions & 0 deletions vault/data_source_ad_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ func adAccessCredentialsDataSource() *schema.Resource {
Type: schema.TypeString,
Computed: true,
Description: "Password for the service account.",
Sensitive: true,
},
"last_password": {
Type: schema.TypeString,
Computed: true,
Description: "Last known password for the service account.",
Sensitive: true,
},
"username": {
Type: schema.TypeString,
Expand Down
1 change: 1 addition & 0 deletions vault/data_source_aws_access_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func awsAccessCredentialsDataSource() *schema.Resource {
Type: schema.TypeString,
Computed: true,
Description: "AWS security token read from Vault. (Only returned if type is 'sts').",
Sensitive: true,
},

consts.FieldLeaseID: {
Expand Down
1 change: 1 addition & 0 deletions vault/data_source_azure_access_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func azureAccessCredentialsDataSource() *schema.Resource {
Type: schema.TypeString,
Computed: true,
Description: "The client secret for credentials to query the Azure APIs.",
Sensitive: true,
},
consts.FieldLeaseID: {
Type: schema.TypeString,
Expand Down
1 change: 1 addition & 0 deletions vault/data_source_nomad_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func nomadAccessCredentialsDataSource() *schema.Resource {
Type: schema.TypeString,
Computed: true,
Description: "Used to make requests to Nomad and should be kept private.",
Sensitive: true,
},
},
}
Expand Down
40 changes: 30 additions & 10 deletions vault/resource_raft_autopilot.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ var (
"max_trailing_logs": 1000,
"min_quorum": 3,
"server_stabilization_time": "10s",
"disable_upgrade_migration": false,
}
)

Expand Down Expand Up @@ -63,7 +62,6 @@ func raftAutopilotConfigResource() *schema.Resource {
"disable_upgrade_migration": {
Type: schema.TypeBool,
Description: "Disables automatically upgrading Vault using autopilot. (Enterprise-only)",
Default: autopilotDefaults["disable_upgrade_migration"],
Optional: true,
},
}
Expand All @@ -73,6 +71,9 @@ func raftAutopilotConfigResource() *schema.Resource {
Read: ReadWrapper(readAutopilotConfigResource),
Delete: deleteAutopilotConfigResource,
Schema: fields,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
}
}

Expand All @@ -82,14 +83,33 @@ func createOrUpdateAutopilotConfigResource(d *schema.ResourceData, meta interfac
return e
}

c := map[string]interface{}{
"cleanup_dead_servers": d.Get("cleanup_dead_servers").(bool),
"last_contact_threshold": d.Get("last_contact_threshold").(string),
"dead_server_last_contact_threshold": d.Get("dead_server_last_contact_threshold").(string),
"max_trailing_logs": d.Get("max_trailing_logs").(int),
"min_quorum": d.Get("min_quorum").(int),
"server_stabilization_time": d.Get("server_stabilization_time").(string),
"disable_upgrade_migration": d.Get("disable_upgrade_migration").(bool),
fields := []string{
"cleanup_dead_servers",
"last_contact_threshold",
"dead_server_last_contact_threshold",
"max_trailing_logs",
"min_quorum",
"server_stabilization_time",
}

c := map[string]interface{}{}

for _, k := range fields {
if v, ok := d.GetOk(k); ok {
c[k] = v
}
}

isEnterprise := provider.IsEnterpriseSupported(meta)
isAPISupported := provider.IsAPISupported(meta, provider.VaultVersion111)
enterpriseAPIField := "disable_upgrade_migration"
val, ok := d.GetOk(enterpriseAPIField)

if (!isAPISupported || !isEnterprise) && ok {
return fmt.Errorf("%s is not supported by "+
"this version of vault", enterpriseAPIField)
} else if (isAPISupported && isEnterprise) && ok {
c[enterpriseAPIField] = val
}

log.Print("[DEBUG] Configuring autopilot")
Expand Down
33 changes: 18 additions & 15 deletions vault/resource_raft_autopilot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,41 @@ import (
)

func TestAccRaftAutopilotConfig_basic(t *testing.T) {
resourceName := "vault_raft_autopilot.test"

resource.Test(t, resource.TestCase{
Providers: testProviders,
PreCheck: func() {
testutil.TestAccPreCheck(t)
testutil.TestEntPreCheck(t)
testutil.SkipTestEnvSet(t, "SKIP_RAFT_TESTS")
},
CheckDestroy: testAccRaftAutopilotConfigCheckDestroy,
Steps: []resource.TestStep{
{
Config: testAccRaftAutopilotConfig_basic(true, "12h0m0s", 3),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "cleanup_dead_servers", "true"),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "dead_server_last_contact_threshold", "12h0m0s"),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "last_contact_threshold", autopilotDefaults["last_contact_threshold"].(string)),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "max_trailing_logs", strconv.Itoa(autopilotDefaults["max_trailing_logs"].(int))),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "min_quorum", strconv.Itoa(autopilotDefaults["min_quorum"].(int))),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "server_stabilization_time", autopilotDefaults["server_stabilization_time"].(string)),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "disable_upgrade_migration", "false"),
resource.TestCheckResourceAttr(resourceName, "cleanup_dead_servers", "true"),
resource.TestCheckResourceAttr(resourceName, "dead_server_last_contact_threshold", "12h0m0s"),
resource.TestCheckResourceAttr(resourceName, "last_contact_threshold", autopilotDefaults["last_contact_threshold"].(string)),
resource.TestCheckResourceAttr(resourceName, "max_trailing_logs", strconv.Itoa(autopilotDefaults["max_trailing_logs"].(int))),
resource.TestCheckResourceAttr(resourceName, "min_quorum", strconv.Itoa(autopilotDefaults["min_quorum"].(int))),
resource.TestCheckResourceAttr(resourceName, "server_stabilization_time", autopilotDefaults["server_stabilization_time"].(string)),
resource.TestCheckResourceAttr(resourceName, "disable_upgrade_migration", "false"),
),
},
{
Config: testAccRaftAutopilotConfig_updated(true, true, "30s", "20s", "50s", 100, 5),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "cleanup_dead_servers", "true"),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "dead_server_last_contact_threshold", "30s"),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "last_contact_threshold", "20s"),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "max_trailing_logs", "100"),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "min_quorum", "5"),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "server_stabilization_time", "50s"),
resource.TestCheckResourceAttr("vault_raft_autopilot.test", "disable_upgrade_migration", "true"),
resource.TestCheckResourceAttr(resourceName, "cleanup_dead_servers", "true"),
resource.TestCheckResourceAttr(resourceName, "dead_server_last_contact_threshold", "30s"),
resource.TestCheckResourceAttr(resourceName, "last_contact_threshold", "20s"),
resource.TestCheckResourceAttr(resourceName, "max_trailing_logs", "100"),
resource.TestCheckResourceAttr(resourceName, "min_quorum", "5"),
resource.TestCheckResourceAttr(resourceName, "server_stabilization_time", "50s"),
resource.TestCheckResourceAttr(resourceName, "disable_upgrade_migration", "true"),
),
},
testutil.GetImportTestStep(resourceName, false, nil),
},
})
}
Expand Down
8 changes: 8 additions & 0 deletions website/docs/r/raft_autopilot.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,11 @@ stable in the 'healthy' state before being added to the cluster.
## Attributes Reference

No additional attributes are exported by this resource.

## Import

Raft Autopilot config can be imported using the ID, e.g.

```
$ terraform import vault_raft_autopilot.autopilot sys/storage/raft/autopilot/configuration
```

0 comments on commit f56e4b5

Please sign in to comment.