From daffaf1091f306fd29ebffaf1582b60878404755 Mon Sep 17 00:00:00 2001 From: Huseyin Unal <23301714+husunal@users.noreply.github.com> Date: Fri, 26 Jan 2024 08:45:10 +0000 Subject: [PATCH 1/8] Add inheritable parameter to vault_quota_lease_count --- vault/resource_quota_lease_count.go | 20 ++++++++- vault/resource_quota_lease_count_test.go | 55 +++++++++++++++++------- website/docs/r/quota_lease_count.md | 2 + 3 files changed, 61 insertions(+), 16 deletions(-) diff --git a/vault/resource_quota_lease_count.go b/vault/resource_quota_lease_count.go index 99768d545a..7dc635afb6 100644 --- a/vault/resource_quota_lease_count.go +++ b/vault/resource_quota_lease_count.go @@ -54,6 +54,12 @@ func quotaLeaseCountResource() *schema.Resource { Optional: true, Description: "If set on a quota where path is set to an auth mount with a concept of roles (such as /auth/approle/), this will make the quota restrict login requests to that mount that are made with the specified role.", }, + "inheritable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "If set to true on a quota where path is set to a namespace, the same quota will be cumulatively applied to all child namespace. The inheritable parameter cannot be set to true if the path does not specify a namespace. Only the quotas associated with the root namespace are inheritable by default.", + }, }, } } @@ -74,6 +80,12 @@ func quotaLeaseCountCreate(d *schema.ResourceData, meta interface{}) error { data["path"] = d.Get("path").(string) data["max_leases"] = d.Get("max_leases").(int) + if data["path"] == "" && d.Get("inheritable") == nil { + data["inheritable"] = true + } else if v, ok := d.GetOkExists("inheritable"); ok { + data["inheritable"] = v.(bool) + } + if provider.IsAPISupported(meta, provider.VaultVersion112) { if v, ok := d.GetOk(consts.FieldRole); ok { data[consts.FieldRole] = v @@ -111,7 +123,7 @@ func quotaLeaseCountRead(d *schema.ResourceData, meta interface{}) error { return nil } - fields := []string{"path", "max_leases", "name"} + fields := []string{"path", "max_leases", "name", "inheritable"} if provider.IsAPISupported(meta, provider.VaultVersion112) { fields = append(fields, consts.FieldRole) } @@ -143,6 +155,12 @@ func quotaLeaseCountUpdate(d *schema.ResourceData, meta interface{}) error { data["path"] = d.Get(consts.FieldPath).(string) data["max_leases"] = d.Get("max_leases").(int) + if data["path"] == "" && d.Get("inheritable") == nil { + data["inheritable"] = true + } else if v, ok := d.GetOkExists("inheritable"); ok { + data["inheritable"] = v.(bool) + } + if provider.IsAPISupported(meta, provider.VaultVersion112) { if v, ok := d.GetOk(consts.FieldRole); ok { data[consts.FieldRole] = v diff --git a/vault/resource_quota_lease_count_test.go b/vault/resource_quota_lease_count_test.go index 4a256f20cd..4ef0409025 100644 --- a/vault/resource_quota_lease_count_test.go +++ b/vault/resource_quota_lease_count_test.go @@ -21,6 +21,7 @@ func TestQuotaLeaseCount(t *testing.T) { ns := "ns-" + name leaseCount := "1001" newLeaseCount := "2001" + inheritable := false resourceName := "vault_quota_lease_count.foobar" resource.Test(t, resource.TestCase{ @@ -29,27 +30,39 @@ func TestQuotaLeaseCount(t *testing.T) { CheckDestroy: testQuotaLeaseCountCheckDestroy([]string{leaseCount, newLeaseCount}), Steps: []resource.TestStep{ { - Config: testQuotaLeaseCountConfig(ns, name, "", leaseCount), + Config: testQuotaLeaseCountConfig(ns, name, "", leaseCount, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/"), resource.TestCheckResourceAttr(resourceName, "max_leases", leaseCount), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), ), }, { - Config: testQuotaLeaseCountConfig(ns, name, "", newLeaseCount), + Config: testQuotaLeaseCountConfig(ns, name, "", newLeaseCount, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/"), resource.TestCheckResourceAttr(resourceName, "max_leases", newLeaseCount), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), ), }, { - Config: testQuotaLeaseCountConfig(ns, name, "sys/", newLeaseCount), + Config: testQuotaLeaseCountConfig(ns, name, "sys/", newLeaseCount, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/sys/"), resource.TestCheckResourceAttr(resourceName, "max_leases", newLeaseCount), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), + ), + }, + { + Config: testQuotaLeaseCountConfig(ns, name, "", newLeaseCount, true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/"), + resource.TestCheckResourceAttr(resourceName, "max_leases", newLeaseCount), + resource.TestCheckResourceAttr(resourceName, "inheritable", "true"), ), }, }, @@ -58,10 +71,12 @@ func TestQuotaLeaseCount(t *testing.T) { func TestQuotaLeaseCountWithRole(t *testing.T) { name := acctest.RandomWithPrefix("lease-count") + ns := "ns-" + name backend := acctest.RandomWithPrefix("approle") role := acctest.RandomWithPrefix("test-role") leaseCount := "1001" newLeaseCount := "2001" + inheritable := false resourceName := "vault_quota_lease_count.foobar" resource.Test(t, resource.TestCase{ @@ -76,21 +91,23 @@ func TestQuotaLeaseCountWithRole(t *testing.T) { ), Steps: []resource.TestStep{ { - Config: testQuotaLeaseCountWithRoleConfig(backend, role, name, leaseCount), + Config: testQuotaLeaseCountWithRoleConfig(ns, backend, role, name, leaseCount, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, consts.FieldPath, fmt.Sprintf("auth/%s/", backend)), + resource.TestCheckResourceAttr(resourceName, consts.FieldPath, fmt.Sprintf("%s/auth/%s/", ns, backend)), resource.TestCheckResourceAttr(resourceName, "max_leases", leaseCount), resource.TestCheckResourceAttr(resourceName, consts.FieldRole, role), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), ), }, { - Config: testQuotaLeaseCountWithRoleConfig(backend, role, name, newLeaseCount), + Config: testQuotaLeaseCountWithRoleConfig(ns, backend, role, name, newLeaseCount, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, consts.FieldPath, fmt.Sprintf("auth/%s/", backend)), + resource.TestCheckResourceAttr(resourceName, consts.FieldPath, fmt.Sprintf("%s/auth/%s/", ns, backend)), resource.TestCheckResourceAttr(resourceName, "max_leases", newLeaseCount), resource.TestCheckResourceAttr(resourceName, consts.FieldRole, role), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), ), }, testutil.GetImportTestStep(resourceName, false, nil), @@ -118,28 +135,35 @@ func testQuotaLeaseCountCheckDestroy(leaseCounts []string) resource.TestCheckFun } // Caution: Don't set test max_leases values too low or other tests running concurrently might fail -func testQuotaLeaseCountConfig(ns, name, path, maxLeases string) string { +func testQuotaLeaseCountConfig(ns, name, path, maxLeases string, inheritable bool) string { return fmt.Sprintf(` resource "vault_namespace" "test" { path = "%s" } resource "vault_quota_lease_count" "foobar" { - name = "%s" - path = "${vault_namespace.test.path}/%s" - max_leases = %s + name = "%s" + path = "${vault_namespace.test.path}/%s" + max_leases = %s + inheritable = %t } -`, ns, name, path, maxLeases) +`, ns, name, path, maxLeases, inheritable) } -func testQuotaLeaseCountWithRoleConfig(backend, role, name, maxLeases string) string { +func testQuotaLeaseCountWithRoleConfig(ns, backend, role, name, maxLeases string, inheritable bool) string { return fmt.Sprintf(` +resource "vault_namespace" "test" { + path = "%s" +} + resource "vault_auth_backend" "approle" { + namespace = vault_namespace.test.path type = "approle" path = "%s" } resource "vault_approle_auth_backend_role" "role" { + namespace = vault_namespace.test.path backend = vault_auth_backend.approle.path role_name = "%s" token_policies = ["default", "dev", "prod"] @@ -147,9 +171,10 @@ resource "vault_approle_auth_backend_role" "role" { resource "vault_quota_lease_count" "foobar" { name = "%s" - path = "auth/${vault_auth_backend.approle.path}/" + path = "${vault_namespace.test.path}/auth/${vault_auth_backend.approle.path}/" role = vault_approle_auth_backend_role.role.role_name max_leases = %s + inheritable = %t } -`, backend, role, name, maxLeases) +`, ns, backend, role, name, maxLeases, inheritable) } diff --git a/website/docs/r/quota_lease_count.md b/website/docs/r/quota_lease_count.md index 32c55425a6..5a94e735f9 100644 --- a/website/docs/r/quota_lease_count.md +++ b/website/docs/r/quota_lease_count.md @@ -50,6 +50,8 @@ The following arguments are supported: * `role` - (Optional) If set on a quota where `path` is set to an auth mount with a concept of roles (such as /auth/approle/), this will make the quota restrict login requests to that mount that are made with the specified role. +* `inheritable` - (Optional) If set to `true` on a quota where path is set to a namespace, the same quota will be cumulatively applied to all child namespace. The inheritable parameter cannot be set to `true` if the path does not specify a namespace. Only the quotas associated with the root namespace are inheritable by default. + ## Attributes Reference No additional attributes are exported by this resource. From 81151d5595cb8ae5440c25f1539fcd0e0fbf1ac9 Mon Sep 17 00:00:00 2001 From: Huseyin Unal <23301714+husunal@users.noreply.github.com> Date: Fri, 26 Jan 2024 08:48:07 +0000 Subject: [PATCH 2/8] Add inheritable parameter to vault_quota_rate_limit --- vault/resource_quota_rate_limit.go | 20 ++++- vault/resource_quota_rate_limit_test.go | 114 +++++++++++++++++++----- website/docs/r/quota_rate_limit.md | 2 + 3 files changed, 115 insertions(+), 21 deletions(-) diff --git a/vault/resource_quota_rate_limit.go b/vault/resource_quota_rate_limit.go index 5308e9f0b3..d796912ae2 100644 --- a/vault/resource_quota_rate_limit.go +++ b/vault/resource_quota_rate_limit.go @@ -66,6 +66,12 @@ func quotaRateLimitResource() *schema.Resource { Optional: true, Description: "If set on a quota where path is set to an auth mount with a concept of roles (such as /auth/approle/), this will make the quota restrict login requests to that mount that are made with the specified role.", }, + "inheritable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "If set to true on a quota where path is set to a namespace, the same quota will be cumulatively applied to all child namespace. The inheritable parameter cannot be set to true if the path does not specify a namespace. Only the quotas associated with the root namespace are inheritable by default.", + }, }, } } @@ -94,6 +100,12 @@ func quotaRateLimitCreate(d *schema.ResourceData, meta interface{}) error { data["block_interval"] = v } + if data["path"] == "" && d.Get("inheritable") == nil { + data["inheritable"] = true + } else if v, ok := d.GetOkExists("inheritable"); ok { + data["inheritable"] = v.(bool) + } + if provider.IsAPISupported(meta, provider.VaultVersion112) { if v, ok := d.GetOk(consts.FieldRole); ok { data[consts.FieldRole] = v @@ -131,7 +143,7 @@ func quotaRateLimitRead(d *schema.ResourceData, meta interface{}) error { return nil } - fields := []string{"path", "rate", "interval", "block_interval", "name"} + fields := []string{"path", "rate", "interval", "block_interval", "name", "inheritable"} if provider.IsAPISupported(meta, provider.VaultVersion112) { fields = append(fields, consts.FieldRole) } @@ -171,6 +183,12 @@ func quotaRateLimitUpdate(d *schema.ResourceData, meta interface{}) error { data["block_interval"] = v } + if data["path"] == "" && d.Get("inheritable") == nil { + data["inheritable"] = true + } else if v, ok := d.GetOkExists("inheritable"); ok { + data["inheritable"] = v.(bool) + } + if provider.IsAPISupported(meta, provider.VaultVersion112) { if v, ok := d.GetOk(consts.FieldRole); ok { data[consts.FieldRole] = v diff --git a/vault/resource_quota_rate_limit_test.go b/vault/resource_quota_rate_limit_test.go index 1d5ba2123e..96497b49e7 100644 --- a/vault/resource_quota_rate_limit_test.go +++ b/vault/resource_quota_rate_limit_test.go @@ -29,39 +29,45 @@ func TestQuotaRateLimit(t *testing.T) { name := acctest.RandomWithPrefix("tf-test") rateLimit := randomQuotaRateString() newRateLimit := randomQuotaRateString() + inheritable := true + resourceName := "vault_quota_rate_limit.foobar" + resource.Test(t, resource.TestCase{ ProviderFactories: providerFactories, PreCheck: func() { testutil.TestAccPreCheck(t) }, CheckDestroy: testQuotaRateLimitCheckDestroy([]string{rateLimit, newRateLimit}), Steps: []resource.TestStep{ { - Config: testQuotaRateLimitConfig(name, "", rateLimit, 1, 0), + Config: testQuotaRateLimitConfig(name, "", rateLimit, 1, 0, inheritable), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "name", name), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "path", ""), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "rate", rateLimit), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "interval", "1"), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "block_interval", "0"), + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "path", ""), + resource.TestCheckResourceAttr(resourceName, "rate", rateLimit), + resource.TestCheckResourceAttr(resourceName, "interval", "1"), + resource.TestCheckResourceAttr(resourceName, "block_interval", "0"), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), ), }, { - Config: testQuotaRateLimitConfig(name, "", newRateLimit, 60, 120), + Config: testQuotaRateLimitConfig(name, "", newRateLimit, 60, 120, inheritable), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "name", name), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "path", ""), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "rate", newRateLimit), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "interval", "60"), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "block_interval", "120"), + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "path", ""), + resource.TestCheckResourceAttr(resourceName, "rate", newRateLimit), + resource.TestCheckResourceAttr(resourceName, "interval", "60"), + resource.TestCheckResourceAttr(resourceName, "block_interval", "120"), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), ), }, { - Config: testQuotaRateLimitConfig(name, "sys/", newRateLimit, 60, 120), + Config: testQuotaRateLimitConfig(name, "", newRateLimit, 60, 120, inheritable), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "name", name), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "path", "sys/"), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "rate", newRateLimit), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "interval", "60"), - resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "block_interval", "120"), + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "path", ""), + resource.TestCheckResourceAttr(resourceName, "rate", newRateLimit), + resource.TestCheckResourceAttr(resourceName, "interval", "60"), + resource.TestCheckResourceAttr(resourceName, "block_interval", "120"), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), ), }, }, @@ -102,6 +108,56 @@ func TestQuotaRateLimitWithRole(t *testing.T) { }) } +func TestQuotaRateLimitWithNamespace(t *testing.T) { + name := acctest.RandomWithPrefix("tf-test") + ns := "ns-" + name + rateLimit := randomQuotaRateString() + newRateLimit := randomQuotaRateString() + inheritable := true + resourceName := "vault_quota_rate_limit.foobar" + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + PreCheck: func() { testutil.TestAccPreCheck(t) }, + CheckDestroy: testQuotaRateLimitCheckDestroy([]string{rateLimit, newRateLimit}), + Steps: []resource.TestStep{ + { + Config: testQuotaRateLimitWithNamespaceConfig(ns, name, "", rateLimit, 1, 0, inheritable), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "path", ns+"/"), + resource.TestCheckResourceAttr(resourceName, "rate", rateLimit), + resource.TestCheckResourceAttr(resourceName, "interval", "1"), + resource.TestCheckResourceAttr(resourceName, "block_interval", "0"), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), + ), + }, + { + Config: testQuotaRateLimitWithNamespaceConfig(ns, name, "", newRateLimit, 60, 120, inheritable), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "path", ns+"/"), + resource.TestCheckResourceAttr(resourceName, "rate", newRateLimit), + resource.TestCheckResourceAttr(resourceName, "interval", "60"), + resource.TestCheckResourceAttr(resourceName, "block_interval", "120"), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), + ), + }, + { + Config: testQuotaRateLimitWithNamespaceConfig(ns, name, "", newRateLimit, 60, 120, false), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "path", ns+"/"), + resource.TestCheckResourceAttr(resourceName, "rate", newRateLimit), + resource.TestCheckResourceAttr(resourceName, "interval", "60"), + resource.TestCheckResourceAttr(resourceName, "block_interval", "120"), + resource.TestCheckResourceAttr(resourceName, "inheritable", "false"), + ), + }, + }, + }) +} + func testQuotaRateLimitCheckDestroy(rateLimits []string) resource.TestCheckFunc { return func(s *terraform.State) error { client := testProvider.Meta().(*provider.ProviderMeta).MustGetClient() @@ -122,7 +178,7 @@ func testQuotaRateLimitCheckDestroy(rateLimits []string) resource.TestCheckFunc } // Caution: Don't set test rate values too low or other tests running concurrently might fail -func testQuotaRateLimitConfig(name, path, rate string, interval, blockInterval int) string { +func testQuotaRateLimitConfig(name, path, rate string, interval, blockInterval int, inheritable bool) string { return fmt.Sprintf(` resource "vault_quota_rate_limit" "foobar" { name = "%s" @@ -130,8 +186,26 @@ resource "vault_quota_rate_limit" "foobar" { rate = %s interval = %d block_interval = %d + inheritable = %t +} +`, name, path, rate, interval, blockInterval, inheritable) +} + +func testQuotaRateLimitWithNamespaceConfig(ns, name, path, rate string, interval, blockInterval int, inheritable bool) string { + return fmt.Sprintf(` +resource "vault_namespace" "test" { + path = "%s" + } + +resource "vault_quota_rate_limit" "foobar" { + name = "%s" + path = "${vault_namespace.test.path}/%s" + rate = %s + interval = %d + block_interval = %d + inheritable = %t } -`, name, path, rate, interval, blockInterval) +`, ns, name, path, rate, interval, blockInterval, inheritable) } func testQuotaRateLimitWithRoleConfig(backend, role, name, rate string, interval, blockInterval int) string { diff --git a/website/docs/r/quota_rate_limit.md b/website/docs/r/quota_rate_limit.md index ee808e9504..16b2d3e748 100644 --- a/website/docs/r/quota_rate_limit.md +++ b/website/docs/r/quota_rate_limit.md @@ -53,6 +53,8 @@ The following arguments are supported: * `role` - (Optional) If set on a quota where `path` is set to an auth mount with a concept of roles (such as /auth/approle/), this will make the quota restrict login requests to that mount that are made with the specified role. +* `inheritable` - (Optional) If set to `true` on a quota where path is set to a namespace, the same quota will be cumulatively applied to all child namespace. The inheritable parameter cannot be set to `true` if the path does not specify a namespace. Only the quotas associated with the root namespace are inheritable by default. + ## Attributes Reference No additional attributes are exported by this resource. From e54935f55d448c038f4b3bb94ffe0885f3519b12 Mon Sep 17 00:00:00 2001 From: Huseyin Unal <23301714+husunal@users.noreply.github.com> Date: Fri, 26 Jan 2024 09:02:57 +0000 Subject: [PATCH 3/8] Update PreCheck function in TestQuotaRateLimitWithNamespace --- vault/resource_quota_rate_limit_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vault/resource_quota_rate_limit_test.go b/vault/resource_quota_rate_limit_test.go index 96497b49e7..02629b995e 100644 --- a/vault/resource_quota_rate_limit_test.go +++ b/vault/resource_quota_rate_limit_test.go @@ -118,7 +118,7 @@ func TestQuotaRateLimitWithNamespace(t *testing.T) { resource.Test(t, resource.TestCase{ ProviderFactories: providerFactories, - PreCheck: func() { testutil.TestAccPreCheck(t) }, + PreCheck: func() { testutil.TestEntPreCheck(t) }, CheckDestroy: testQuotaRateLimitCheckDestroy([]string{rateLimit, newRateLimit}), Steps: []resource.TestStep{ { From 8cf4ba6a4cf4708d21ad48843fdaa70be0e39fec Mon Sep 17 00:00:00 2001 From: Huseyin Unal <23301714+husunal@users.noreply.github.com> Date: Thu, 8 Feb 2024 20:19:20 +0100 Subject: [PATCH 4/8] Update quota lease count --- vault/resource_quota_lease_count.go | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/vault/resource_quota_lease_count.go b/vault/resource_quota_lease_count.go index 7dc635afb6..260abe6faa 100644 --- a/vault/resource_quota_lease_count.go +++ b/vault/resource_quota_lease_count.go @@ -57,7 +57,6 @@ func quotaLeaseCountResource() *schema.Resource { "inheritable": { Type: schema.TypeBool, Optional: true, - Computed: true, Description: "If set to true on a quota where path is set to a namespace, the same quota will be cumulatively applied to all child namespace. The inheritable parameter cannot be set to true if the path does not specify a namespace. Only the quotas associated with the root namespace are inheritable by default.", }, }, @@ -80,10 +79,10 @@ func quotaLeaseCountCreate(d *schema.ResourceData, meta interface{}) error { data["path"] = d.Get("path").(string) data["max_leases"] = d.Get("max_leases").(int) - if data["path"] == "" && d.Get("inheritable") == nil { - data["inheritable"] = true - } else if v, ok := d.GetOkExists("inheritable"); ok { - data["inheritable"] = v.(bool) + if provider.IsAPISupported(meta, provider.VaultVersion115) { + if v, ok := d.GetOkExists("inheritable"); ok { + data["inheritable"] = v.(bool) + } } if provider.IsAPISupported(meta, provider.VaultVersion112) { @@ -123,11 +122,17 @@ func quotaLeaseCountRead(d *schema.ResourceData, meta interface{}) error { return nil } - fields := []string{"path", "max_leases", "name", "inheritable"} + fields := []string{"path", "max_leases", "name"} if provider.IsAPISupported(meta, provider.VaultVersion112) { fields = append(fields, consts.FieldRole) } + if provider.IsAPISupported(meta, provider.VaultVersion115) { + if _, ok := d.GetOkExists("inheritable"); ok { + fields = append(fields, "inheritable") + } + } + for _, k := range fields { v, ok := resp.Data[k] if ok { @@ -155,18 +160,18 @@ func quotaLeaseCountUpdate(d *schema.ResourceData, meta interface{}) error { data["path"] = d.Get(consts.FieldPath).(string) data["max_leases"] = d.Get("max_leases").(int) - if data["path"] == "" && d.Get("inheritable") == nil { - data["inheritable"] = true - } else if v, ok := d.GetOkExists("inheritable"); ok { - data["inheritable"] = v.(bool) - } - if provider.IsAPISupported(meta, provider.VaultVersion112) { if v, ok := d.GetOk(consts.FieldRole); ok { data[consts.FieldRole] = v } } + if provider.IsAPISupported(meta, provider.VaultVersion115) { + if d.HasChange("inheritable") { + data["inheritable"] = d.Get("inheritable") + } + } + _, err := client.Logical().Write(path, data) if err != nil { d.SetId("") From 63a05e995cda8e7240c93131bd3a7960eb8446b9 Mon Sep 17 00:00:00 2001 From: Huseyin Unal <23301714+husunal@users.noreply.github.com> Date: Tue, 7 May 2024 16:16:41 +0100 Subject: [PATCH 5/8] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bf532ad0e..6cac1c090e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ FEATURES: * Add support for `iam_tags` in `vault_aws_secret_backend_role` ([#2231](https://github.com/hashicorp/terraform-provider-vault/pull/2231)). +* Add support for `inheritable` on `vault_quota_rate_limit` and `vault_quota_lease_count`. Requires Vault 1.15+.: ([#2133](https://github.com/hashicorp/terraform-provider-vault/pull/2133)). IMPROVEMENTS: * return a useful error when delete fails for the `vault_jwt_auth_backend_role` resource: ([#2232](https://github.com/hashicorp/terraform-provider-vault/pull/2232)) From 3cb21ad4cf1078dec2e458c1d491bb47b59562da Mon Sep 17 00:00:00 2001 From: Huseyin Unal <23301714+husunal@users.noreply.github.com> Date: Tue, 7 May 2024 16:18:01 +0100 Subject: [PATCH 6/8] Update vault_quota_lease_count --- vault/resource_quota_lease_count.go | 4 +- vault/resource_quota_lease_count_test.go | 176 +++++++++++++++++++++-- website/docs/r/quota_lease_count.md | 2 +- 3 files changed, 167 insertions(+), 15 deletions(-) diff --git a/vault/resource_quota_lease_count.go b/vault/resource_quota_lease_count.go index 260abe6faa..656cbf19b4 100644 --- a/vault/resource_quota_lease_count.go +++ b/vault/resource_quota_lease_count.go @@ -167,8 +167,8 @@ func quotaLeaseCountUpdate(d *schema.ResourceData, meta interface{}) error { } if provider.IsAPISupported(meta, provider.VaultVersion115) { - if d.HasChange("inheritable") { - data["inheritable"] = d.Get("inheritable") + if v, ok := d.GetOkExists("inheritable"); ok { + data["inheritable"] = v.(bool) } } diff --git a/vault/resource_quota_lease_count_test.go b/vault/resource_quota_lease_count_test.go index 4ef0409025..3c97c32c34 100644 --- a/vault/resource_quota_lease_count_test.go +++ b/vault/resource_quota_lease_count_test.go @@ -21,7 +21,6 @@ func TestQuotaLeaseCount(t *testing.T) { ns := "ns-" + name leaseCount := "1001" newLeaseCount := "2001" - inheritable := false resourceName := "vault_quota_lease_count.foobar" resource.Test(t, resource.TestCase{ @@ -30,7 +29,102 @@ func TestQuotaLeaseCount(t *testing.T) { CheckDestroy: testQuotaLeaseCountCheckDestroy([]string{leaseCount, newLeaseCount}), Steps: []resource.TestStep{ { - Config: testQuotaLeaseCountConfig(ns, name, "", leaseCount, inheritable), + Config: testQuotaLeaseCountConfig(ns, name, "", leaseCount), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/"), + resource.TestCheckResourceAttr(resourceName, "max_leases", leaseCount), + ), + }, + { + Config: testQuotaLeaseCountConfig(ns, name, "", newLeaseCount), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/"), + resource.TestCheckResourceAttr(resourceName, "max_leases", newLeaseCount), + ), + }, + { + Config: testQuotaLeaseCountConfig(ns, name, "sys/", newLeaseCount), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/sys/"), + resource.TestCheckResourceAttr(resourceName, "max_leases", newLeaseCount), + ), + }, + { + Config: testQuotaLeaseCountConfigRootPath(name, "", newLeaseCount), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "path", ""), + resource.TestCheckResourceAttr(resourceName, "max_leases", newLeaseCount), + ), + }, + }, + }) +} + +func TestQuotaLeaseCountWithRole(t *testing.T) { + name := acctest.RandomWithPrefix("lease-count") + ns := "ns-" + name + backend := acctest.RandomWithPrefix("approle") + role := acctest.RandomWithPrefix("test-role") + leaseCount := "1001" + newLeaseCount := "2001" + resourceName := "vault_quota_lease_count.foobar" + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + PreCheck: func() { + testutil.TestEntPreCheck(t) + SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion112) + }, + CheckDestroy: resource.ComposeTestCheckFunc( + testQuotaLeaseCountCheckDestroy([]string{leaseCount, newLeaseCount}), + testAccCheckAppRoleAuthBackendRoleDestroy, + ), + Steps: []resource.TestStep{ + { + Config: testQuotaLeaseCountWithRoleConfig(ns, backend, role, name, leaseCount), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, consts.FieldPath, fmt.Sprintf("%s/auth/%s/", ns, backend)), + resource.TestCheckResourceAttr(resourceName, "max_leases", leaseCount), + resource.TestCheckResourceAttr(resourceName, consts.FieldRole, role), + ), + }, + { + Config: testQuotaLeaseCountWithRoleConfig(ns, backend, role, name, newLeaseCount), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, consts.FieldPath, fmt.Sprintf("%s/auth/%s/", ns, backend)), + resource.TestCheckResourceAttr(resourceName, "max_leases", newLeaseCount), + resource.TestCheckResourceAttr(resourceName, consts.FieldRole, role), + ), + }, + testutil.GetImportTestStep(resourceName, false, nil), + }, + }) +} + +func TestQuotaLeaseCountInheritable(t *testing.T) { + name := acctest.RandomWithPrefix("tf-test") + ns := "ns-" + name + leaseCount := "1001" + newLeaseCount := "2001" + inheritable := false + resourceName := "vault_quota_lease_count.foobar" + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + PreCheck: func() { + testutil.TestEntPreCheck(t) + SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion115) + }, + CheckDestroy: testQuotaLeaseCountCheckDestroy([]string{leaseCount, newLeaseCount}), + Steps: []resource.TestStep{ + { + Config: testQuotaLeaseCountConfigInheritable(ns, name, "", leaseCount, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/"), @@ -39,7 +133,7 @@ func TestQuotaLeaseCount(t *testing.T) { ), }, { - Config: testQuotaLeaseCountConfig(ns, name, "", newLeaseCount, inheritable), + Config: testQuotaLeaseCountConfigInheritable(ns, name, "", newLeaseCount, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/"), @@ -48,7 +142,7 @@ func TestQuotaLeaseCount(t *testing.T) { ), }, { - Config: testQuotaLeaseCountConfig(ns, name, "sys/", newLeaseCount, inheritable), + Config: testQuotaLeaseCountConfigInheritable(ns, name, "sys/", newLeaseCount, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/sys/"), @@ -57,7 +151,7 @@ func TestQuotaLeaseCount(t *testing.T) { ), }, { - Config: testQuotaLeaseCountConfig(ns, name, "", newLeaseCount, true), + Config: testQuotaLeaseCountConfigInheritable(ns, name, "", newLeaseCount, true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, consts.FieldPath, ns+"/"), @@ -69,7 +163,7 @@ func TestQuotaLeaseCount(t *testing.T) { }) } -func TestQuotaLeaseCountWithRole(t *testing.T) { +func TestQuotaLeaseCountWithRoleInheritable(t *testing.T) { name := acctest.RandomWithPrefix("lease-count") ns := "ns-" + name backend := acctest.RandomWithPrefix("approle") @@ -83,7 +177,7 @@ func TestQuotaLeaseCountWithRole(t *testing.T) { ProviderFactories: providerFactories, PreCheck: func() { testutil.TestEntPreCheck(t) - SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion112) + SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion115) }, CheckDestroy: resource.ComposeTestCheckFunc( testQuotaLeaseCountCheckDestroy([]string{leaseCount, newLeaseCount}), @@ -91,7 +185,7 @@ func TestQuotaLeaseCountWithRole(t *testing.T) { ), Steps: []resource.TestStep{ { - Config: testQuotaLeaseCountWithRoleConfig(ns, backend, role, name, leaseCount, inheritable), + Config: testQuotaLeaseCountWithRoleConfigInheritable(ns, backend, role, name, leaseCount, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, consts.FieldPath, fmt.Sprintf("%s/auth/%s/", ns, backend)), @@ -101,7 +195,7 @@ func TestQuotaLeaseCountWithRole(t *testing.T) { ), }, { - Config: testQuotaLeaseCountWithRoleConfig(ns, backend, role, name, newLeaseCount, inheritable), + Config: testQuotaLeaseCountWithRoleConfigInheritable(ns, backend, role, name, newLeaseCount, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, consts.FieldPath, fmt.Sprintf("%s/auth/%s/", ns, backend)), @@ -110,7 +204,12 @@ func TestQuotaLeaseCountWithRole(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), ), }, - testutil.GetImportTestStep(resourceName, false, nil), + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"inheritable"}, + }, }, }) } @@ -135,7 +234,60 @@ func testQuotaLeaseCountCheckDestroy(leaseCounts []string) resource.TestCheckFun } // Caution: Don't set test max_leases values too low or other tests running concurrently might fail -func testQuotaLeaseCountConfig(ns, name, path, maxLeases string, inheritable bool) string { +func testQuotaLeaseCountConfig(ns, name, path, maxLeases string) string { + return fmt.Sprintf(` +resource "vault_namespace" "test" { + path = "%s" +} + +resource "vault_quota_lease_count" "foobar" { + name = "%s" + path = "${vault_namespace.test.path}/%s" + max_leases = %s +} +`, ns, name, path, maxLeases) +} + +func testQuotaLeaseCountConfigRootPath(name, path, maxLeases string) string { + return fmt.Sprintf(` +resource "vault_quota_lease_count" "foobar" { + name = "%s" + path = "%s" + max_leases = %s +} +`, name, path, maxLeases) +} + +func testQuotaLeaseCountWithRoleConfig(ns, backend, role, name, maxLeases string) string { + return fmt.Sprintf(` +resource "vault_namespace" "test" { + path = "%s" + } + +resource "vault_auth_backend" "approle" { + namespace = vault_namespace.test.path + type = "approle" + path = "%s" +} + +resource "vault_approle_auth_backend_role" "role" { + namespace = vault_namespace.test.path + backend = vault_auth_backend.approle.path + role_name = "%s" + token_policies = ["default", "dev", "prod"] +} + +resource "vault_quota_lease_count" "foobar" { + name = "%s" + path = "${vault_namespace.test.path}/auth/${vault_auth_backend.approle.path}/" + role = vault_approle_auth_backend_role.role.role_name + max_leases = %s +} +`, ns, backend, role, name, maxLeases) +} + +// Caution: Don't set test max_leases values too low or other tests running concurrently might fail +func testQuotaLeaseCountConfigInheritable(ns, name, path, maxLeases string, inheritable bool) string { return fmt.Sprintf(` resource "vault_namespace" "test" { path = "%s" @@ -150,7 +302,7 @@ resource "vault_quota_lease_count" "foobar" { `, ns, name, path, maxLeases, inheritable) } -func testQuotaLeaseCountWithRoleConfig(ns, backend, role, name, maxLeases string, inheritable bool) string { +func testQuotaLeaseCountWithRoleConfigInheritable(ns, backend, role, name, maxLeases string, inheritable bool) string { return fmt.Sprintf(` resource "vault_namespace" "test" { path = "%s" diff --git a/website/docs/r/quota_lease_count.md b/website/docs/r/quota_lease_count.md index 5a94e735f9..0d49ae5234 100644 --- a/website/docs/r/quota_lease_count.md +++ b/website/docs/r/quota_lease_count.md @@ -50,7 +50,7 @@ The following arguments are supported: * `role` - (Optional) If set on a quota where `path` is set to an auth mount with a concept of roles (such as /auth/approle/), this will make the quota restrict login requests to that mount that are made with the specified role. -* `inheritable` - (Optional) If set to `true` on a quota where path is set to a namespace, the same quota will be cumulatively applied to all child namespace. The inheritable parameter cannot be set to `true` if the path does not specify a namespace. Only the quotas associated with the root namespace are inheritable by default. +* `inheritable` - (Optional) If set to `true` on a quota where path is set to a namespace, the same quota will be cumulatively applied to all child namespace. The inheritable parameter cannot be set to `true` if the path does not specify a namespace. Only the quotas associated with the root namespace are inheritable by default. Requires Vault 1.15+. ## Attributes Reference From 88ec91c89137906738cf488097ad2f7e902cf06d Mon Sep 17 00:00:00 2001 From: Huseyin Unal <23301714+husunal@users.noreply.github.com> Date: Tue, 7 May 2024 16:18:19 +0100 Subject: [PATCH 7/8] Update vault_quota_rate_limit --- vault/resource_quota_rate_limit.go | 25 ++-- vault/resource_quota_rate_limit_test.go | 173 +++++++++++++++++------- website/docs/r/quota_rate_limit.md | 2 +- 3 files changed, 139 insertions(+), 61 deletions(-) diff --git a/vault/resource_quota_rate_limit.go b/vault/resource_quota_rate_limit.go index d796912ae2..a0466729bf 100644 --- a/vault/resource_quota_rate_limit.go +++ b/vault/resource_quota_rate_limit.go @@ -69,7 +69,6 @@ func quotaRateLimitResource() *schema.Resource { "inheritable": { Type: schema.TypeBool, Optional: true, - Computed: true, Description: "If set to true on a quota where path is set to a namespace, the same quota will be cumulatively applied to all child namespace. The inheritable parameter cannot be set to true if the path does not specify a namespace. Only the quotas associated with the root namespace are inheritable by default.", }, }, @@ -100,10 +99,10 @@ func quotaRateLimitCreate(d *schema.ResourceData, meta interface{}) error { data["block_interval"] = v } - if data["path"] == "" && d.Get("inheritable") == nil { - data["inheritable"] = true - } else if v, ok := d.GetOkExists("inheritable"); ok { - data["inheritable"] = v.(bool) + if provider.IsAPISupported(meta, provider.VaultVersion115) { + if v, ok := d.GetOkExists("inheritable"); ok { + data["inheritable"] = v.(bool) + } } if provider.IsAPISupported(meta, provider.VaultVersion112) { @@ -143,11 +142,17 @@ func quotaRateLimitRead(d *schema.ResourceData, meta interface{}) error { return nil } - fields := []string{"path", "rate", "interval", "block_interval", "name", "inheritable"} + fields := []string{"path", "rate", "interval", "block_interval", "name"} if provider.IsAPISupported(meta, provider.VaultVersion112) { fields = append(fields, consts.FieldRole) } + if provider.IsAPISupported(meta, provider.VaultVersion115) { + if _, ok := d.GetOkExists("inheritable"); ok { + fields = append(fields, "inheritable") + } + } + for _, k := range fields { v, ok := resp.Data[k] if ok { @@ -183,10 +188,10 @@ func quotaRateLimitUpdate(d *schema.ResourceData, meta interface{}) error { data["block_interval"] = v } - if data["path"] == "" && d.Get("inheritable") == nil { - data["inheritable"] = true - } else if v, ok := d.GetOkExists("inheritable"); ok { - data["inheritable"] = v.(bool) + if provider.IsAPISupported(meta, provider.VaultVersion115) { + if v, ok := d.GetOkExists("inheritable"); ok { + data["inheritable"] = v.(bool) + } } if provider.IsAPISupported(meta, provider.VaultVersion112) { diff --git a/vault/resource_quota_rate_limit_test.go b/vault/resource_quota_rate_limit_test.go index 02629b995e..ed5fc1d4bb 100644 --- a/vault/resource_quota_rate_limit_test.go +++ b/vault/resource_quota_rate_limit_test.go @@ -29,45 +29,39 @@ func TestQuotaRateLimit(t *testing.T) { name := acctest.RandomWithPrefix("tf-test") rateLimit := randomQuotaRateString() newRateLimit := randomQuotaRateString() - inheritable := true - resourceName := "vault_quota_rate_limit.foobar" - resource.Test(t, resource.TestCase{ ProviderFactories: providerFactories, PreCheck: func() { testutil.TestAccPreCheck(t) }, CheckDestroy: testQuotaRateLimitCheckDestroy([]string{rateLimit, newRateLimit}), Steps: []resource.TestStep{ { - Config: testQuotaRateLimitConfig(name, "", rateLimit, 1, 0, inheritable), + Config: testQuotaRateLimitConfig(name, "", rateLimit, 1, 0), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "path", ""), - resource.TestCheckResourceAttr(resourceName, "rate", rateLimit), - resource.TestCheckResourceAttr(resourceName, "interval", "1"), - resource.TestCheckResourceAttr(resourceName, "block_interval", "0"), - resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "name", name), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "path", ""), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "rate", rateLimit), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "interval", "1"), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "block_interval", "0"), ), }, { - Config: testQuotaRateLimitConfig(name, "", newRateLimit, 60, 120, inheritable), + Config: testQuotaRateLimitConfig(name, "", newRateLimit, 60, 120), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "path", ""), - resource.TestCheckResourceAttr(resourceName, "rate", newRateLimit), - resource.TestCheckResourceAttr(resourceName, "interval", "60"), - resource.TestCheckResourceAttr(resourceName, "block_interval", "120"), - resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "name", name), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "path", ""), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "rate", newRateLimit), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "interval", "60"), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "block_interval", "120"), ), }, { - Config: testQuotaRateLimitConfig(name, "", newRateLimit, 60, 120, inheritable), + Config: testQuotaRateLimitConfig(name, "sys/", newRateLimit, 60, 120), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "path", ""), - resource.TestCheckResourceAttr(resourceName, "rate", newRateLimit), - resource.TestCheckResourceAttr(resourceName, "interval", "60"), - resource.TestCheckResourceAttr(resourceName, "block_interval", "120"), - resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "name", name), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "path", "sys/"), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "rate", newRateLimit), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "interval", "60"), + resource.TestCheckResourceAttr("vault_quota_rate_limit.foobar", "block_interval", "120"), ), }, }, @@ -79,6 +73,7 @@ func TestQuotaRateLimitWithRole(t *testing.T) { backend := acctest.RandomWithPrefix("approle") role := acctest.RandomWithPrefix("test-role") rateLimit := randomQuotaRateString() + newRateLimit := randomQuotaRateString() resourceName := "vault_quota_rate_limit.foobar" resource.Test(t, resource.TestCase{ @@ -103,12 +98,75 @@ func TestQuotaRateLimitWithRole(t *testing.T) { resource.TestCheckResourceAttr(resourceName, consts.FieldRole, role), ), }, + { + Config: testQuotaRateLimitWithRoleConfig(backend, role, name, newRateLimit, 1, 0), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, consts.FieldPath, fmt.Sprintf("auth/%s/", backend)), + resource.TestCheckResourceAttr(resourceName, "rate", newRateLimit), + resource.TestCheckResourceAttr(resourceName, "interval", "1"), + resource.TestCheckResourceAttr(resourceName, "block_interval", "0"), + resource.TestCheckResourceAttr(resourceName, consts.FieldRole, role), + ), + }, testutil.GetImportTestStep(resourceName, false, nil), }, }) } -func TestQuotaRateLimitWithNamespace(t *testing.T) { +func TestQuotaRateLimitInheritable(t *testing.T) { + name := acctest.RandomWithPrefix("tf-test") + rateLimit := randomQuotaRateString() + newRateLimit := randomQuotaRateString() + inheritable := true + resourceName := "vault_quota_rate_limit.foobar" + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + PreCheck: func() { + testutil.TestEntPreCheck(t) + SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion115) + }, + CheckDestroy: testQuotaRateLimitCheckDestroy([]string{rateLimit, newRateLimit}), + Steps: []resource.TestStep{ + { + Config: testQuotaRateLimitConfigInheritable(name, "", rateLimit, 1, 0, inheritable), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "path", ""), + resource.TestCheckResourceAttr(resourceName, "rate", rateLimit), + resource.TestCheckResourceAttr(resourceName, "interval", "1"), + resource.TestCheckResourceAttr(resourceName, "block_interval", "0"), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), + ), + }, + { + Config: testQuotaRateLimitConfigInheritable(name, "", newRateLimit, 60, 120, inheritable), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "path", ""), + resource.TestCheckResourceAttr(resourceName, "rate", newRateLimit), + resource.TestCheckResourceAttr(resourceName, "interval", "60"), + resource.TestCheckResourceAttr(resourceName, "block_interval", "120"), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), + ), + }, + { + Config: testQuotaRateLimitConfigInheritable(name, "", newRateLimit, 60, 120, inheritable), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "path", ""), + resource.TestCheckResourceAttr(resourceName, "rate", newRateLimit), + resource.TestCheckResourceAttr(resourceName, "interval", "60"), + resource.TestCheckResourceAttr(resourceName, "block_interval", "120"), + resource.TestCheckResourceAttr(resourceName, "inheritable", fmt.Sprintf("%t", inheritable)), + ), + }, + }, + }) +} + +func TestQuotaRateLimitWithNamespaceInheritable(t *testing.T) { name := acctest.RandomWithPrefix("tf-test") ns := "ns-" + name rateLimit := randomQuotaRateString() @@ -118,11 +176,14 @@ func TestQuotaRateLimitWithNamespace(t *testing.T) { resource.Test(t, resource.TestCase{ ProviderFactories: providerFactories, - PreCheck: func() { testutil.TestEntPreCheck(t) }, - CheckDestroy: testQuotaRateLimitCheckDestroy([]string{rateLimit, newRateLimit}), + PreCheck: func() { + testutil.TestEntPreCheck(t) + SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion115) + }, + CheckDestroy: testQuotaRateLimitCheckDestroy([]string{rateLimit, newRateLimit}), Steps: []resource.TestStep{ { - Config: testQuotaRateLimitWithNamespaceConfig(ns, name, "", rateLimit, 1, 0, inheritable), + Config: testQuotaRateLimitWithNamespaceConfigInheritable(ns, name, "", rateLimit, 1, 0, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, "path", ns+"/"), @@ -133,7 +194,7 @@ func TestQuotaRateLimitWithNamespace(t *testing.T) { ), }, { - Config: testQuotaRateLimitWithNamespaceConfig(ns, name, "", newRateLimit, 60, 120, inheritable), + Config: testQuotaRateLimitWithNamespaceConfigInheritable(ns, name, "", newRateLimit, 60, 120, inheritable), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, "path", ns+"/"), @@ -144,7 +205,7 @@ func TestQuotaRateLimitWithNamespace(t *testing.T) { ), }, { - Config: testQuotaRateLimitWithNamespaceConfig(ns, name, "", newRateLimit, 60, 120, false), + Config: testQuotaRateLimitWithNamespaceConfigInheritable(ns, name, "", newRateLimit, 60, 120, false), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, "path", ns+"/"), @@ -178,7 +239,7 @@ func testQuotaRateLimitCheckDestroy(rateLimits []string) resource.TestCheckFunc } // Caution: Don't set test rate values too low or other tests running concurrently might fail -func testQuotaRateLimitConfig(name, path, rate string, interval, blockInterval int, inheritable bool) string { +func testQuotaRateLimitConfig(name, path, rate string, interval, blockInterval int) string { return fmt.Sprintf(` resource "vault_quota_rate_limit" "foobar" { name = "%s" @@ -186,26 +247,8 @@ resource "vault_quota_rate_limit" "foobar" { rate = %s interval = %d block_interval = %d - inheritable = %t } -`, name, path, rate, interval, blockInterval, inheritable) -} - -func testQuotaRateLimitWithNamespaceConfig(ns, name, path, rate string, interval, blockInterval int, inheritable bool) string { - return fmt.Sprintf(` -resource "vault_namespace" "test" { - path = "%s" - } - -resource "vault_quota_rate_limit" "foobar" { - name = "%s" - path = "${vault_namespace.test.path}/%s" - rate = %s - interval = %d - block_interval = %d - inheritable = %t -} -`, ns, name, path, rate, interval, blockInterval, inheritable) +`, name, path, rate, interval, blockInterval) } func testQuotaRateLimitWithRoleConfig(backend, role, name, rate string, interval, blockInterval int) string { @@ -231,3 +274,33 @@ resource "vault_quota_rate_limit" "foobar" { } `, backend, role, name, rate, interval, blockInterval) } + +func testQuotaRateLimitConfigInheritable(name, path, rate string, interval, blockInterval int, inheritable bool) string { + return fmt.Sprintf(` +resource "vault_quota_rate_limit" "foobar" { + name = "%s" + path = "%s" + rate = %s + interval = %d + block_interval = %d + inheritable = %t +} +`, name, path, rate, interval, blockInterval, inheritable) +} + +func testQuotaRateLimitWithNamespaceConfigInheritable(ns, name, path, rate string, interval, blockInterval int, inheritable bool) string { + return fmt.Sprintf(` +resource "vault_namespace" "test" { + path = "%s" + } + +resource "vault_quota_rate_limit" "foobar" { + name = "%s" + path = "${vault_namespace.test.path}/%s" + rate = %s + interval = %d + block_interval = %d + inheritable = %t +} +`, ns, name, path, rate, interval, blockInterval, inheritable) +} diff --git a/website/docs/r/quota_rate_limit.md b/website/docs/r/quota_rate_limit.md index 16b2d3e748..ef4ee8d926 100644 --- a/website/docs/r/quota_rate_limit.md +++ b/website/docs/r/quota_rate_limit.md @@ -53,7 +53,7 @@ The following arguments are supported: * `role` - (Optional) If set on a quota where `path` is set to an auth mount with a concept of roles (such as /auth/approle/), this will make the quota restrict login requests to that mount that are made with the specified role. -* `inheritable` - (Optional) If set to `true` on a quota where path is set to a namespace, the same quota will be cumulatively applied to all child namespace. The inheritable parameter cannot be set to `true` if the path does not specify a namespace. Only the quotas associated with the root namespace are inheritable by default. +* `inheritable` - (Optional) If set to `true` on a quota where path is set to a namespace, the same quota will be cumulatively applied to all child namespace. The inheritable parameter cannot be set to `true` if the path does not specify a namespace. Only the quotas associated with the root namespace are inheritable by default. Requires Vault 1.15+. ## Attributes Reference From 333cce021c8629ee2bd3f4dbc3b6a8851c737a28 Mon Sep 17 00:00:00 2001 From: Huseyin Unal <23301714+husunal@users.noreply.github.com> Date: Tue, 7 May 2024 22:48:56 +0100 Subject: [PATCH 8/8] Skip tests in root if there is "Default lease count quota" --- vault/resource_quota_lease_count_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vault/resource_quota_lease_count_test.go b/vault/resource_quota_lease_count_test.go index 3c97c32c34..b00477ebf3 100644 --- a/vault/resource_quota_lease_count_test.go +++ b/vault/resource_quota_lease_count_test.go @@ -52,6 +52,24 @@ func TestQuotaLeaseCount(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "max_leases", newLeaseCount), ), }, + }, + }) +} + +func TestQuotaLeaseCountRoot(t *testing.T) { + name := acctest.RandomWithPrefix("tf-test") + leaseCount := "1001" + newLeaseCount := "2001" + resourceName := "vault_quota_lease_count.foobar" + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + PreCheck: func() { + testutil.TestEntPreCheck(t) + SkipIfAPIVersionGTE(t, testProvider.Meta(), provider.VaultVersion116) + }, + CheckDestroy: testQuotaLeaseCountCheckDestroy([]string{leaseCount, newLeaseCount}), + Steps: []resource.TestStep{ { Config: testQuotaLeaseCountConfigRootPath(name, "", newLeaseCount), Check: resource.ComposeTestCheckFunc(