Skip to content

Commit 81f1c03

Browse files
authored
Merge pull request #5912 from steve-thousand/ACCT-10424/account-owned-token-tests
ACCT-10424 adding tests for account owned tokens and fixing bugs
2 parents 5f6debe + 425e6e8 commit 81f1c03

7 files changed

+318
-2
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
package account_token_test
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest"
9+
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils"
10+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
11+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
12+
)
13+
14+
func TestAccAccountToken_Basic(t *testing.T) {
15+
rnd := utils.GenerateRandomResourceName()
16+
resourceID := "cloudflare_account_token." + rnd
17+
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
18+
permissionID := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
19+
20+
var policyId string
21+
22+
resource.Test(t, resource.TestCase{
23+
PreCheck: func() { acctest.TestAccPreCheck(t) },
24+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
25+
Steps: []resource.TestStep{
26+
{
27+
Config: testAccCloudflareAccountTokenWithoutCondition(rnd, accountID, rnd, permissionID),
28+
Check: resource.ComposeTestCheckFunc(
29+
resource.TestCheckResourceAttr(resourceID, "name", rnd),
30+
resource.TestCheckResourceAttrSet(resourceID, "policies.0.id"),
31+
resource.TestCheckResourceAttrWith(resourceID, "policies.0.id", func(value string) error {
32+
policyId = value
33+
return nil
34+
}),
35+
resource.TestCheckResourceAttr(resourceID, "policies.0.permission_groups.0.id", permissionID),
36+
),
37+
},
38+
{
39+
Config: testAccCloudflareAccountTokenWithoutCondition(rnd, accountID, rnd+"-updated", permissionID),
40+
Check: resource.ComposeTestCheckFunc(
41+
resource.TestCheckResourceAttr(resourceID, "name", rnd+"-updated"),
42+
resource.TestCheckResourceAttrSet(resourceID, "policies.0.id"),
43+
resource.TestCheckResourceAttrWith(resourceID, "policies.0.id", func(value string) error {
44+
if value != policyId {
45+
return fmt.Errorf("policy ID changed from %s to %s", policyId, value)
46+
}
47+
return nil
48+
}),
49+
resource.TestCheckResourceAttr(resourceID, "policies.0.permission_groups.0.id", permissionID),
50+
),
51+
},
52+
},
53+
})
54+
}
55+
56+
func TestAccAccountToken_DoesNotSetConditions(t *testing.T) {
57+
rnd := utils.GenerateRandomResourceName()
58+
name := "cloudflare_account_token." + rnd
59+
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
60+
permissionID := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
61+
62+
resource.Test(t, resource.TestCase{
63+
PreCheck: func() { acctest.TestAccPreCheck(t) },
64+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
65+
Steps: []resource.TestStep{
66+
{
67+
Config: testAccCloudflareAccountTokenWithoutCondition(rnd, accountID, rnd, permissionID),
68+
Check: resource.ComposeTestCheckFunc(
69+
resource.TestCheckResourceAttr(name, "name", rnd),
70+
resource.TestCheckNoResourceAttr(name, "condition.request_ip.0.in"),
71+
resource.TestCheckNoResourceAttr(name, "condition.request_ip.0.not_in"),
72+
),
73+
},
74+
},
75+
})
76+
}
77+
78+
func testAccCloudflareAccountTokenWithoutCondition(resourceName, accountId, rnd, permissionID string) string {
79+
return acctest.LoadTestCase("account_token-without-condition.tf", resourceName, accountId, rnd, permissionID)
80+
}
81+
82+
func TestAccAccountToken_SetIndividualCondition(t *testing.T) {
83+
rnd := utils.GenerateRandomResourceName()
84+
name := "cloudflare_account_token." + rnd
85+
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
86+
permissionID := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
87+
88+
resource.Test(t, resource.TestCase{
89+
PreCheck: func() { acctest.TestAccPreCheck(t) },
90+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
91+
Steps: []resource.TestStep{
92+
{
93+
Config: testAccCloudflareAccountTokenWithIndividualCondition(rnd, accountID, permissionID),
94+
Check: resource.ComposeTestCheckFunc(
95+
resource.TestCheckResourceAttr(name, "name", rnd),
96+
resource.TestCheckResourceAttr(name, "condition.request_ip.in.0", "192.0.2.1/32"),
97+
resource.TestCheckNoResourceAttr(name, "condition.request_ip.not_in"),
98+
),
99+
},
100+
},
101+
})
102+
}
103+
104+
func testAccCloudflareAccountTokenWithIndividualCondition(rnd, accountID, permissionID string) string {
105+
return acctest.LoadTestCase("account_token-with-individual-condition.tf", rnd, accountID, permissionID)
106+
}
107+
108+
func TestAccAccountToken_SetAllCondition(t *testing.T) {
109+
rnd := utils.GenerateRandomResourceName()
110+
name := "cloudflare_account_token." + rnd
111+
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
112+
permissionID := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
113+
114+
resource.Test(t, resource.TestCase{
115+
PreCheck: func() { acctest.TestAccPreCheck(t) },
116+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
117+
Steps: []resource.TestStep{
118+
{
119+
Config: testAccCloudflareAccountTokenWithAllCondition(rnd, accountID, permissionID),
120+
Check: resource.ComposeTestCheckFunc(
121+
resource.TestCheckResourceAttr(name, "name", rnd),
122+
resource.TestCheckResourceAttr(name, "condition.request_ip.in.0", "192.0.2.1/32"),
123+
resource.TestCheckResourceAttr(name, "condition.request_ip.not_in.0", "198.51.100.1/32"),
124+
),
125+
},
126+
},
127+
})
128+
}
129+
130+
func testAccCloudflareAccountTokenWithAllCondition(rnd, accountID, permissionID string) string {
131+
return acctest.LoadTestCase("account_token-with-all-condition.tf", rnd, accountID, permissionID)
132+
}
133+
134+
func TestAccAccountToken_TokenTTL(t *testing.T) {
135+
rnd := utils.GenerateRandomResourceName()
136+
name := "cloudflare_account_token." + rnd
137+
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
138+
permissionID := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
139+
140+
resource.Test(t, resource.TestCase{
141+
PreCheck: func() { acctest.TestAccPreCheck(t) },
142+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
143+
Steps: []resource.TestStep{
144+
{
145+
Config: testAccCloudflareAccountTokenWithTTL(rnd, accountID, permissionID),
146+
Check: resource.ComposeTestCheckFunc(
147+
resource.TestCheckResourceAttr(name, "name", rnd),
148+
resource.TestCheckResourceAttr(name, "not_before", "2018-07-01T05:20:00Z"),
149+
resource.TestCheckResourceAttr(name, "expires_on", "2032-01-01T00:00:00Z"),
150+
),
151+
},
152+
},
153+
})
154+
}
155+
156+
func testAccCloudflareAccountTokenWithTTL(rnd, accountID, permissionID string) string {
157+
return acctest.LoadTestCase("account_token-with-ttl.tf", rnd, accountID, permissionID)
158+
}
159+
160+
func TestAccAccountToken_PermissionGroupOrder(t *testing.T) {
161+
rnd := utils.GenerateRandomResourceName()
162+
name := "cloudflare_account_token." + rnd
163+
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
164+
permissionID1 := "82e64a83756745bbbb1c9c2701bf816b" // DNS read
165+
permissionID2 := "e199d584e69344eba202452019deafe3" // Disable ESC read
166+
167+
resource.Test(t, resource.TestCase{
168+
PreCheck: func() { acctest.TestAccPreCheck(t) },
169+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
170+
Steps: []resource.TestStep{
171+
{
172+
Config: acctest.LoadTestCase("account_token-permissiongroup-order.tf", rnd, accountID, permissionID1, permissionID2),
173+
Check: resource.ComposeTestCheckFunc(
174+
resource.TestCheckResourceAttr(name, "name", rnd),
175+
resource.TestCheckResourceAttr(name, "policies.0.permission_groups.0.id", permissionID1),
176+
resource.TestCheckResourceAttr(name, "policies.0.permission_groups.1.id", permissionID2),
177+
),
178+
},
179+
{
180+
Config: acctest.LoadTestCase("account_token-permissiongroup-order.tf", rnd, accountID, permissionID2, permissionID1),
181+
// changing the order of permission groups should not affect plan
182+
ConfigPlanChecks: resource.ConfigPlanChecks{
183+
PreApply: []plancheck.PlanCheck{
184+
plancheck.ExpectEmptyPlan(),
185+
},
186+
},
187+
},
188+
},
189+
})
190+
191+
resource.Test(t, resource.TestCase{
192+
PreCheck: func() { acctest.TestAccPreCheck(t) },
193+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
194+
Steps: []resource.TestStep{
195+
{
196+
Config: acctest.LoadTestCase("account_token-permissiongroup-order.tf", rnd, accountID, permissionID2, permissionID1),
197+
Check: resource.ComposeTestCheckFunc(
198+
resource.TestCheckResourceAttr(name, "name", rnd),
199+
resource.TestCheckResourceAttr(name, "policies.0.permission_groups.0.id", permissionID1),
200+
resource.TestCheckResourceAttr(name, "policies.0.permission_groups.1.id", permissionID2),
201+
),
202+
},
203+
{
204+
Config: acctest.LoadTestCase("account_token-permissiongroup-order.tf", rnd, accountID, permissionID2, permissionID1),
205+
// re-applying same change does not produce drift
206+
ConfigPlanChecks: resource.ConfigPlanChecks{
207+
PreApply: []plancheck.PlanCheck{
208+
plancheck.ExpectEmptyPlan(),
209+
},
210+
},
211+
},
212+
{
213+
Config: acctest.LoadTestCase("account_token-permissiongroup-order.tf", rnd, accountID, permissionID1, permissionID2),
214+
// changing the order of permission groups should not affect plan
215+
ConfigPlanChecks: resource.ConfigPlanChecks{
216+
PreApply: []plancheck.PlanCheck{
217+
plancheck.ExpectEmptyPlan(),
218+
},
219+
},
220+
},
221+
},
222+
})
223+
}

internal/services/account_token/schema.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,17 @@ func ResourceSchema(ctx context.Context) schema.Schema {
3535
Description: "Token name.",
3636
Required: true,
3737
},
38-
"policies": schema.SetNestedAttribute{
38+
"policies": schema.ListNestedAttribute{
3939
Description: "List of access policies assigned to the token.",
4040
Required: true,
4141
NestedObject: schema.NestedAttributeObject{
4242
Attributes: map[string]schema.Attribute{
4343
"id": schema.StringAttribute{
4444
Description: "Policy identifier.",
4545
Computed: true,
46+
PlanModifiers: []planmodifier.String{
47+
stringplanmodifier.UseStateForUnknown(),
48+
},
4649
},
4750
"effect": schema.StringAttribute{
4851
Description: "Allow or deny operations against the resources.\nAvailable values: \"allow\", \"deny\".",
@@ -51,7 +54,7 @@ func ResourceSchema(ctx context.Context) schema.Schema {
5154
stringvalidator.OneOfCaseInsensitive("allow", "deny"),
5255
},
5356
},
54-
"permission_groups": schema.ListNestedAttribute{
57+
"permission_groups": schema.SetNestedAttribute{
5558
Description: "A set of permission groups that are specified to the policy.",
5659
Required: true,
5760
NestedObject: schema.NestedAttributeObject{
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
resource "cloudflare_account_token" "%[1]s" {
2+
name = "%[1]s"
3+
account_id = "%[2]s"
4+
5+
policies = [{
6+
effect = "allow"
7+
permission_groups = [{
8+
id = "%[3]s"
9+
},{
10+
id = "%[4]s"
11+
}]
12+
resources = {
13+
"com.cloudflare.api.account.%[2]s" = "*"
14+
}
15+
}]
16+
}
17+
18+
data "cloudflare_account_token" "%[1]s" {
19+
account_id = "%[2]s"
20+
token_id = cloudflare_account_token.%[1]s.id
21+
depends_on = [cloudflare_account_token.%[1]s]
22+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
resource "cloudflare_account_token" "%[1]s" {
2+
name = "%[1]s"
3+
account_id = "%[2]s"
4+
5+
policies = [{
6+
effect = "allow"
7+
permission_groups = [{
8+
id = "%[3]s"
9+
}]
10+
resources = {
11+
"com.cloudflare.api.account.%[2]s" = "*"
12+
}
13+
}]
14+
15+
condition = {
16+
request_ip = {
17+
in = ["192.0.2.1/32"]
18+
not_in = ["198.51.100.1/32"]
19+
}
20+
}
21+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
resource "cloudflare_account_token" "%[1]s" {
2+
name = "%[1]s"
3+
account_id = "%[2]s"
4+
5+
policies = [{
6+
effect = "allow"
7+
permission_groups = [{
8+
id = "%[3]s"
9+
}]
10+
resources = {
11+
"com.cloudflare.api.account.%[2]s" = "*"
12+
}
13+
}]
14+
15+
condition = {
16+
request_ip = {
17+
in = ["192.0.2.1/32"]
18+
}
19+
}
20+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
resource "cloudflare_account_token" "%[1]s" {
2+
name = "%[1]s"
3+
account_id = "%[2]s"
4+
5+
policies = [{
6+
effect = "allow"
7+
permission_groups = [{ id = "%[3]s" }]
8+
resources = {
9+
"com.cloudflare.api.account.%[2]s" = "*"
10+
}
11+
}]
12+
13+
not_before = "2018-07-01T05:20:00Z"
14+
expires_on = "2032-01-01T00:00:00Z"
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
resource "cloudflare_account_token" "%[1]s" {
2+
name = "%[3]s"
3+
account_id = "%[2]s"
4+
5+
policies = [{
6+
effect = "allow"
7+
permission_groups = [{ id = "%[4]s" }]
8+
resources = {
9+
"com.cloudflare.api.account.%[2]s" = "*"
10+
}
11+
}]
12+
}

0 commit comments

Comments
 (0)