Skip to content

Commit dd65448

Browse files
feat(iam): add new data source iam_policy
1 parent 97801bb commit dd65448

File tree

9 files changed

+1587
-18
lines changed

9 files changed

+1587
-18
lines changed

docs/data-sources/iam_policy.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
subcategory: "IAM"
3+
page_title: "Scaleway: scaleway_iam_policy"
4+
---
5+
6+
# scaleway_iam_policy
7+
8+
Use this data source to get information on an existing IAM policy based on its ID.
9+
For more information refer to the [IAM API documentation](https://developers.scaleway.com/en/products/iam/api/).
10+
11+
## Example Usage
12+
13+
```hcl
14+
# Get policy by id
15+
data "scaleway_iam_policy" "find_by_id" {
16+
policy_id = "11111111-1111-1111-1111-111111111111"
17+
}
18+
19+
# Get policy by name
20+
data "scaleway_iam_policy" "find_by_name" {
21+
name = "my_policy"
22+
}
23+
```
24+
25+
## Argument Reference
26+
27+
- `name` - (Optional) The name of the IAM policy.
28+
- `policy_id` - (Optional) The ID of the IAM policy.
29+
30+
-> **Note** You must specify at least one: `name` and/or `policy_id`.
31+
32+
## Attributes Reference
33+
34+
In addition to all arguments above, the following attributes are exported:
35+
36+
- `id` - The ID of the IAM policy.
37+
- `created_at` - The date and time of the creation of the policy.
38+
- `updated_at` - The date and time of the last update of the policy.
39+
- `editable` - Whether the policy is editable.
40+
- `description` - The description of the IAM policy.
41+
- `tags` - The tags associated with the IAM policy.
42+
- `organization_id` - The ID of the organization the policy is associated with.
43+
- `user_id` - ID of the user the policy is linked to
44+
- `group_id` - ID of the group the policy is linked to
45+
- `application_id` - ID of the application the policy is linked to
46+
- `no_principal` - If the policy doesn't apply to a principal.
47+
- `rule` - List of rules in the policy.
48+
- `organization_id` - ID of organization scoped to the rule.
49+
- `project_ids` - List of project IDs scoped to the rule.
50+
- `permission_set_names` - Names of permission sets bound to the rule.
51+
- `condition` - The condition of the rule.

internal/acctest/fixtures.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func FakeSideProjectProviders(ctx context.Context, tt *TestTools, project *accou
5757
// CreateFakeIAMManager creates a temporary project with a temporary IAM application and policy manager.
5858
//
5959
// The returned function is a cleanup function that should be called when to delete the project.
60-
func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSideProjectTerminateFunc, error) {
60+
func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, *iam.Policy, FakeSideProjectTerminateFunc, error) {
6161
terminateFunctions := []FakeSideProjectTerminateFunc{}
6262
terminate := func() error {
6363
for i := len(terminateFunctions) - 1; i >= 0; i-- {
@@ -81,10 +81,10 @@ func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSid
8181
})
8282
if err != nil {
8383
if err := terminate(); err != nil {
84-
return nil, nil, nil, err
84+
return nil, nil, nil, nil, err
8585
}
8686

87-
return nil, nil, nil, err
87+
return nil, nil, nil, nil, err
8888
}
8989

9090
terminateFunctions = append(terminateFunctions, func() error {
@@ -100,10 +100,10 @@ func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSid
100100
})
101101
if err != nil {
102102
if err := terminate(); err != nil {
103-
return nil, nil, nil, err
103+
return nil, nil, nil, nil, err
104104
}
105105

106-
return nil, nil, nil, err
106+
return nil, nil, nil, nil, err
107107
}
108108

109109
terminateFunctions = append(terminateFunctions, func() error {
@@ -124,10 +124,10 @@ func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSid
124124
})
125125
if err != nil {
126126
if err := terminate(); err != nil {
127-
return nil, nil, nil, err
127+
return nil, nil, nil, nil, err
128128
}
129129

130-
return nil, nil, nil, err
130+
return nil, nil, nil, nil, err
131131
}
132132

133133
terminateFunctions = append(terminateFunctions, func() error {
@@ -142,10 +142,10 @@ func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSid
142142
})
143143
if err != nil {
144144
if err := terminate(); err != nil {
145-
return nil, nil, nil, err
145+
return nil, nil, nil, nil, err
146146
}
147147

148-
return nil, nil, nil, err
148+
return nil, nil, nil, nil, err
149149
}
150150

151151
terminateFunctions = append(terminateFunctions, func() error {
@@ -154,7 +154,7 @@ func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSid
154154
})
155155
})
156156

157-
return project, iamAPIKey, terminate, nil
157+
return project, iamAPIKey, iamPolicy, terminate, nil
158158
}
159159

160160
type FakeSideProjectTerminateFunc func() error
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package iam
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
iam "github.com/scaleway/scaleway-sdk-go/api/iam/v1alpha1"
9+
"github.com/scaleway/scaleway-sdk-go/scw"
10+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/datasource"
11+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
13+
)
14+
15+
func DataSourcePolicy() *schema.Resource {
16+
// Generate datasource schema from resource
17+
dsSchema := datasource.SchemaFromResourceSchema(ResourcePolicy().Schema)
18+
datasource.AddOptionalFieldsToSchema(dsSchema, "name")
19+
20+
dsSchema["name"].ConflictsWith = []string{"policy_id"}
21+
dsSchema["policy_id"] = &schema.Schema{
22+
Type: schema.TypeString,
23+
Optional: true,
24+
Description: "The ID of the policy",
25+
ValidateDiagFunc: verify.IsUUID(),
26+
}
27+
28+
return &schema.Resource{
29+
ReadContext: DataSourceIamPolicyRead,
30+
Schema: dsSchema,
31+
}
32+
}
33+
34+
func DataSourceIamPolicyRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
35+
iamAPI := NewAPI(m)
36+
37+
policyID, policyIDExists := d.GetOk("policy_id")
38+
if !policyIDExists {
39+
policyName := d.Get("name").(string)
40+
41+
res, err := iamAPI.ListPolicies(&iam.ListPoliciesRequest{
42+
PolicyName: types.ExpandStringPtr(policyName),
43+
}, scw.WithContext(ctx))
44+
if err != nil {
45+
return diag.FromErr(err)
46+
}
47+
48+
foundPolicy, err := datasource.FindExact(
49+
res.Policies,
50+
func(s *iam.Policy) bool { return s.Name == policyName },
51+
policyName,
52+
)
53+
if err != nil {
54+
return diag.FromErr(err)
55+
}
56+
57+
policyID = foundPolicy.ID
58+
}
59+
60+
d.SetId(policyID.(string))
61+
62+
err := d.Set("policy_id", policyID)
63+
if err != nil {
64+
return diag.FromErr(err)
65+
}
66+
67+
diags := resourceIamPolicyRead(ctx, d, m)
68+
if diags != nil {
69+
return append(diags, diag.Errorf("failed to read iam policy state")...)
70+
}
71+
72+
if d.Id() == "" {
73+
return diag.Errorf("iam policy (%s) not found", policyID)
74+
}
75+
76+
return nil
77+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package iam_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-testing/terraform"
9+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestAccDataSourcePolicy_Basic(t *testing.T) {
14+
tt := acctest.NewTestTools(t)
15+
defer tt.Cleanup()
16+
17+
ctx := t.Context()
18+
project, iamAPIKey, iamPolicy, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
19+
require.NoError(t, err)
20+
21+
resource.ParallelTest(t, resource.TestCase{
22+
PreCheck: func() { acctest.PreCheck(t) },
23+
ProtoV6ProviderFactories: acctest.FakeSideProjectProviders(ctx, tt, project, iamAPIKey),
24+
CheckDestroy: resource.ComposeAggregateTestCheckFunc(
25+
func(_ *terraform.State) error {
26+
return terminateFakeSideProject()
27+
},
28+
testAccCheckIamPolicyDestroy(tt),
29+
),
30+
Steps: []resource.TestStep{
31+
{
32+
Config: fmt.Sprintf(`
33+
data "scaleway_iam_policy" "by_name" {
34+
name = "%s"
35+
}
36+
37+
data "scaleway_iam_policy" "by_id" {
38+
policy_id = "%s"
39+
}`, iamPolicy.Name, iamPolicy.ID),
40+
Check: resource.ComposeTestCheckFunc(
41+
// Check by name
42+
testAccCheckIamPolicyExists(tt, "data.scaleway_iam_policy.by_name"),
43+
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_name", "name", iamPolicy.Name),
44+
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_name", "application_id", *iamPolicy.ApplicationID),
45+
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_name", "rule.0.organization_id", project.OrganizationID),
46+
// Check by id
47+
testAccCheckIamPolicyExists(tt, "data.scaleway_iam_policy.by_id"),
48+
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_id", "name", iamPolicy.Name),
49+
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_id", "application_id", *iamPolicy.ApplicationID),
50+
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_id", "rule.0.organization_id", project.OrganizationID),
51+
52+
// Ensure both refer to the same policy
53+
resource.TestCheckResourceAttrPair(
54+
"data.scaleway_iam_policy.by_name",
55+
"id",
56+
"data.scaleway_iam_policy.by_id",
57+
"id",
58+
),
59+
),
60+
},
61+
},
62+
})
63+
}

internal/services/iam/policy_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func TestAccPolicy_Basic(t *testing.T) {
1818
defer tt.Cleanup()
1919

2020
ctx := t.Context()
21-
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
21+
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
2222
require.NoError(t, err)
2323

2424
resource.ParallelTest(t, resource.TestCase{
@@ -92,7 +92,7 @@ func TestAccPolicy_NoUpdate(t *testing.T) {
9292
defer tt.Cleanup()
9393

9494
ctx := t.Context()
95-
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
95+
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
9696
require.NoError(t, err)
9797

9898
resource.ParallelTest(t, resource.TestCase{
@@ -155,7 +155,7 @@ func TestAccPolicy_ChangeLinkedEntity(t *testing.T) {
155155
defer tt.Cleanup()
156156

157157
ctx := t.Context()
158-
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
158+
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
159159
require.NoError(t, err)
160160

161161
randAppName := "tf-tests-scaleway-iam-app-policy-permissions"
@@ -261,7 +261,7 @@ func TestAccPolicy_ChangePermissions(t *testing.T) {
261261
defer tt.Cleanup()
262262

263263
ctx := t.Context()
264-
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
264+
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
265265
require.NoError(t, err)
266266

267267
resource.ParallelTest(t, resource.TestCase{
@@ -352,7 +352,7 @@ func TestAccPolicy_ProjectID(t *testing.T) {
352352
defer tt.Cleanup()
353353

354354
ctx := t.Context()
355-
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
355+
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
356356
require.NoError(t, err)
357357

358358
resource.ParallelTest(t, resource.TestCase{
@@ -418,7 +418,7 @@ func TestAccPolicy_Condition(t *testing.T) {
418418
defer tt.Cleanup()
419419

420420
ctx := t.Context()
421-
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
421+
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
422422
require.NoError(t, err)
423423

424424
resource.ParallelTest(t, resource.TestCase{
@@ -513,7 +513,7 @@ func TestAccPolicy_ChangeRulePrincipal(t *testing.T) {
513513
defer tt.Cleanup()
514514

515515
ctx := t.Context()
516-
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
516+
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
517517
require.NoError(t, err)
518518

519519
resource.ParallelTest(t, resource.TestCase{

0 commit comments

Comments
 (0)