Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions docs/data-sources/iam_policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
subcategory: "IAM"
page_title: "Scaleway: scaleway_iam_policy"
---

# scaleway_iam_policy

Use this data source to get information on an existing IAM policy based on its ID.
For more information refer to the [IAM API documentation](https://developers.scaleway.com/en/products/iam/api/).

## Example Usage

```hcl
# Get policy by id
data "scaleway_iam_policy" "find_by_id" {
policy_id = "11111111-1111-1111-1111-111111111111"
}

# Get policy by name
data "scaleway_iam_policy" "find_by_name" {
name = "my_policy"
}
```

## Argument Reference

- `name` - (Optional) The name of the IAM policy.
- `policy_id` - (Optional) The ID of the IAM policy.

-> **Note** You must specify at least one: `name` and/or `policy_id`.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:

- `id` - The ID of the IAM policy.
- `created_at` - The date and time of the creation of the policy.
- `updated_at` - The date and time of the last update of the policy.
- `editable` - Whether the policy is editable.
- `description` - The description of the IAM policy.
- `tags` - The tags associated with the IAM policy.
- `organization_id` - The ID of the organization the policy is associated with.
- `user_id` - ID of the user the policy is linked to
- `group_id` - ID of the group the policy is linked to
- `application_id` - ID of the application the policy is linked to
- `no_principal` - If the policy doesn't apply to a principal.
- `rule` - List of rules in the policy.
- `organization_id` - ID of organization scoped to the rule.
- `project_ids` - List of project IDs scoped to the rule.
- `permission_set_names` - Names of permission sets bound to the rule.
- `condition` - The condition of the rule.
20 changes: 10 additions & 10 deletions internal/acctest/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func FakeSideProjectProviders(ctx context.Context, tt *TestTools, project *accou
// CreateFakeIAMManager creates a temporary project with a temporary IAM application and policy manager.
//
// The returned function is a cleanup function that should be called when to delete the project.
func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSideProjectTerminateFunc, error) {
func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, *iam.Policy, FakeSideProjectTerminateFunc, error) {
terminateFunctions := []FakeSideProjectTerminateFunc{}
terminate := func() error {
for i := len(terminateFunctions) - 1; i >= 0; i-- {
Expand All @@ -81,10 +81,10 @@ func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSid
})
if err != nil {
if err := terminate(); err != nil {
return nil, nil, nil, err
return nil, nil, nil, nil, err
}

return nil, nil, nil, err
return nil, nil, nil, nil, err
}

terminateFunctions = append(terminateFunctions, func() error {
Expand All @@ -100,10 +100,10 @@ func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSid
})
if err != nil {
if err := terminate(); err != nil {
return nil, nil, nil, err
return nil, nil, nil, nil, err
}

return nil, nil, nil, err
return nil, nil, nil, nil, err
}

terminateFunctions = append(terminateFunctions, func() error {
Expand All @@ -124,10 +124,10 @@ func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSid
})
if err != nil {
if err := terminate(); err != nil {
return nil, nil, nil, err
return nil, nil, nil, nil, err
}

return nil, nil, nil, err
return nil, nil, nil, nil, err
}

terminateFunctions = append(terminateFunctions, func() error {
Expand All @@ -142,10 +142,10 @@ func CreateFakeIAMManager(tt *TestTools) (*account.Project, *iam.APIKey, FakeSid
})
if err != nil {
if err := terminate(); err != nil {
return nil, nil, nil, err
return nil, nil, nil, nil, err
}

return nil, nil, nil, err
return nil, nil, nil, nil, err
}

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

return project, iamAPIKey, terminate, nil
return project, iamAPIKey, iamPolicy, terminate, nil
}

type FakeSideProjectTerminateFunc func() error
Expand Down
77 changes: 77 additions & 0 deletions internal/services/iam/policy_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package iam

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
iam "github.com/scaleway/scaleway-sdk-go/api/iam/v1alpha1"
"github.com/scaleway/scaleway-sdk-go/scw"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/datasource"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
)

func DataSourcePolicy() *schema.Resource {
// Generate datasource schema from resource
dsSchema := datasource.SchemaFromResourceSchema(ResourcePolicy().Schema)
datasource.AddOptionalFieldsToSchema(dsSchema, "name")

dsSchema["name"].ConflictsWith = []string{"policy_id"}
dsSchema["policy_id"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "The ID of the policy",
ValidateDiagFunc: verify.IsUUID(),
}

return &schema.Resource{
ReadContext: DataSourceIamPolicyRead,
Schema: dsSchema,
}
}

func DataSourceIamPolicyRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
iamAPI := NewAPI(m)

policyID, policyIDExists := d.GetOk("policy_id")
if !policyIDExists {
policyName := d.Get("name").(string)

res, err := iamAPI.ListPolicies(&iam.ListPoliciesRequest{
PolicyName: types.ExpandStringPtr(policyName),
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

foundPolicy, err := datasource.FindExact(
res.Policies,
func(s *iam.Policy) bool { return s.Name == policyName },
policyName,
)
if err != nil {
return diag.FromErr(err)
}

policyID = foundPolicy.ID
}

d.SetId(policyID.(string))

err := d.Set("policy_id", policyID)
if err != nil {
return diag.FromErr(err)
}

diags := resourceIamPolicyRead(ctx, d, m)
if diags != nil {
return append(diags, diag.Errorf("failed to read iam policy state")...)
}

if d.Id() == "" {
return diag.Errorf("iam policy (%s) not found", policyID)
}

return nil
}
63 changes: 63 additions & 0 deletions internal/services/iam/policy_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package iam_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
"github.com/stretchr/testify/require"
)

func TestAccDataSourcePolicy_Basic(t *testing.T) {
tt := acctest.NewTestTools(t)
defer tt.Cleanup()

ctx := t.Context()
project, iamAPIKey, iamPolicy, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
require.NoError(t, err)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProtoV6ProviderFactories: acctest.FakeSideProjectProviders(ctx, tt, project, iamAPIKey),
CheckDestroy: resource.ComposeAggregateTestCheckFunc(
func(_ *terraform.State) error {
return terminateFakeSideProject()
},
testAccCheckIamPolicyDestroy(tt),
),
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
data "scaleway_iam_policy" "by_name" {
name = "%s"
}

data "scaleway_iam_policy" "by_id" {
policy_id = "%s"
}`, iamPolicy.Name, iamPolicy.ID),
Check: resource.ComposeTestCheckFunc(
// Check by name
testAccCheckIamPolicyExists(tt, "data.scaleway_iam_policy.by_name"),
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_name", "name", iamPolicy.Name),
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_name", "application_id", *iamPolicy.ApplicationID),
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_name", "rule.0.organization_id", project.OrganizationID),
// Check by id
testAccCheckIamPolicyExists(tt, "data.scaleway_iam_policy.by_id"),
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_id", "name", iamPolicy.Name),
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_id", "application_id", *iamPolicy.ApplicationID),
resource.TestCheckResourceAttr("data.scaleway_iam_policy.by_id", "rule.0.organization_id", project.OrganizationID),

// Ensure both refer to the same policy
resource.TestCheckResourceAttrPair(
"data.scaleway_iam_policy.by_name",
"id",
"data.scaleway_iam_policy.by_id",
"id",
),
),
},
},
})
}
14 changes: 7 additions & 7 deletions internal/services/iam/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestAccPolicy_Basic(t *testing.T) {
defer tt.Cleanup()

ctx := t.Context()
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
require.NoError(t, err)

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -92,7 +92,7 @@ func TestAccPolicy_NoUpdate(t *testing.T) {
defer tt.Cleanup()

ctx := t.Context()
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
require.NoError(t, err)

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -155,7 +155,7 @@ func TestAccPolicy_ChangeLinkedEntity(t *testing.T) {
defer tt.Cleanup()

ctx := t.Context()
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
require.NoError(t, err)

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

ctx := t.Context()
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
require.NoError(t, err)

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -352,7 +352,7 @@ func TestAccPolicy_ProjectID(t *testing.T) {
defer tt.Cleanup()

ctx := t.Context()
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
require.NoError(t, err)

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -418,7 +418,7 @@ func TestAccPolicy_Condition(t *testing.T) {
defer tt.Cleanup()

ctx := t.Context()
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
require.NoError(t, err)

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -513,7 +513,7 @@ func TestAccPolicy_ChangeRulePrincipal(t *testing.T) {
defer tt.Cleanup()

ctx := t.Context()
project, iamAPIKey, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
project, iamAPIKey, _, terminateFakeSideProject, err := acctest.CreateFakeIAMManager(tt)
require.NoError(t, err)

resource.ParallelTest(t, resource.TestCase{
Expand Down
Loading
Loading