Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ACCT-4178: Add raw permissions struct to provider #1960

Merged
merged 4 commits into from Nov 16, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changelog/1960.txt
@@ -0,0 +1,7 @@
```release-note:note
datasource/api_token_permission_groups: `permissions` attribute has been deprecated in favour of individual resource level attributes.
```

```release-note:bug
datasource/api_token_permission_groups: add `user`, `account` and `zone` attributes to contain only those specific resource level permissions.
```
43 changes: 32 additions & 11 deletions docs/data-sources/api_token_permission_groups.md
@@ -1,24 +1,45 @@
---
layout: "cloudflare"
page_title: "Cloudflare: cloudflare_api_token_permission_groups"
description: List available API Token Permission Group IDs.
page_title: "cloudflare_api_token_permission_groups Data Source - Cloudflare"
subcategory: ""
description: |-
Use this data source to look up API Token Permission Groups https://developers.cloudflare.com/api/tokens/create/permissions.
Commonly used as references within cloudflare_token resources.
---

# cloudflare_api_token_permission_groups
# cloudflare_api_token_permission_groups (Data Source)

Use this data source to look up [API Token Permission Groups](https://developers.cloudflare.com/api/tokens/create/permissions). Commonly used as references within [`cloudflare_api_token`](/docs/providers/cloudflare/r/api_token.html) resources.
Use this data source to look up [API Token Permission Groups](https://developers.cloudflare.com/api/tokens/create/permissions).
Commonly used as references within [`cloudflare_token`](/docs/providers/cloudflare/r/api_token.html) resources.

## Example Usage

```hcl
data "cloudflare_api_token_permission_groups" "test" {}
```terraform
data "cloudflare_api_token_permission_groups" "all" {}

# Get zone level DNS read permission ID.
output "dns_read_permission_id" {
value = data.cloudflare_api_token_permission_groups.test.permissions["DNS Read"] // 82e64a83756745bbbb1c9c2701bf816b
value = data.cloudflare_api_token_permission_groups.all.zone["DNS Read"] // 82e64a83756745bbbb1c9c2701bf816b
}

# Get account level "Load Balancing: Monitors and Pools Read" permission ID.
output "account_lb_monitors_and_read_id" {
value = data.cloudflare_api_token_permission_groups.all.account["Load Balancing: Monitors and Pools Read"] // 9d24387c6e8544e2bc4024a03991339f
}

# Get user level "Memberships Read" permission ID.
output "user_memberships_read_id" {
value = data.cloudflare_api_token_permission_groups.all.user["Memberships Read"] // 3518d0f75557482e952c6762d3e64903
}
```
<!-- schema generated by tfplugindocs -->
## Schema

### Read-Only

- `account` (Map of String) Map of permissions for account level resources.
- `id` (String) The ID of this resource.
- `permissions` (Map of String, Deprecated) Map of all permissions available. Should not be used as some permissions will overlap resource scope. Instead, use resource level specific attributes.
- `user` (Map of String) Map of permissions for user level resources.
- `zone` (Map of String) Map of permissions for zone level resources.

## Attributes Reference

- `permissions` - A map of permission groups where keys are human-readable permission names
and values are permission IDs.
@@ -0,0 +1,16 @@
data "cloudflare_api_token_permission_groups" "all" {}

# Get zone level DNS read permission ID.
output "dns_read_permission_id" {
value = data.cloudflare_api_token_permission_groups.all.zone["DNS Read"] // 82e64a83756745bbbb1c9c2701bf816b
}

# Get account level "Load Balancing: Monitors and Pools Read" permission ID.
output "account_lb_monitors_and_read_id" {
value = data.cloudflare_api_token_permission_groups.all.account["Load Balancing: Monitors and Pools Read"] // 9d24387c6e8544e2bc4024a03991339f
}

# Get user level "Memberships Read" permission ID.
output "user_memberships_read_id" {
value = data.cloudflare_api_token_permission_groups.all.user["Memberships Read"] // 3518d0f75557482e952c6762d3e64903
}
59 changes: 54 additions & 5 deletions internal/provider/data_source_api_token_permission_groups.go
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"

"github.com/MakeNowJust/heredoc/v2"
"github.com/cloudflare/cloudflare-go"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
Expand All @@ -13,11 +14,31 @@ import (
func dataSourceCloudflareApiTokenPermissionGroups() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceCloudflareApiTokenPermissionGroupsRead,

Description: heredoc.Docf(`
Use this data source to look up [API Token Permission Groups](https://developers.cloudflare.com/api/tokens/create/permissions).
Commonly used as references within [%s](/docs/providers/cloudflare/r/api_token.html) resources.
`, "`cloudflare_token`"),
Schema: map[string]*schema.Schema{
"permissions": {
Computed: true,
Type: schema.TypeMap,
Computed: true,
Type: schema.TypeMap,
Deprecated: "Use specific account, zone or user attributes instead.",
Description: "Map of all permissions available. Should not be used as some permissions will overlap resource scope. Instead, use resource level specific attributes.",
},
"zone": {
Computed: true,
Type: schema.TypeMap,
Description: "Map of permissions for zone level resources.",
},
"account": {
Computed: true,
Type: schema.TypeMap,
Description: "Map of permissions for account level resources.",
},
"user": {
Computed: true,
Type: schema.TypeMap,
Description: "Map of permissions for user level resources.",
},
},
}
Expand All @@ -33,14 +54,42 @@ func dataSourceCloudflareApiTokenPermissionGroupsRead(ctx context.Context, d *sc
}

permissionDetails := make(map[string]interface{}, 0)
zoneScopes := make(map[string]interface{}, 0)
accountScopes := make(map[string]interface{}, 0)
userScopes := make(map[string]interface{}, 0)
ids := []string{}

for _, v := range permissions {
// This is for backwards compatibility and shouldn't be used going forward
// due to some permissions overlapping and returning invalid IDs.
permissionDetails[v.Name] = v.ID
ids = append(ids, v.ID)

switch v.Scopes[0] {
case "com.cloudflare.api.account":
accountScopes[v.Name] = v.ID
case "com.cloudflare.api.account.zone":
zoneScopes[v.Name] = v.ID
case "com.cloudflare.api.user":
userScopes[v.Name] = v.ID
default:
tflog.Warn(ctx, fmt.Sprintf("unknown permission scope found: %s", v.Scopes[0]))
}
}

err = d.Set("permissions", permissionDetails)
if err != nil {
if err = d.Set("account", accountScopes); err != nil {
return diag.FromErr(fmt.Errorf("error setting API Token Permission Groups for accounts: %w", err))
}

if err = d.Set("zone", zoneScopes); err != nil {
return diag.FromErr(fmt.Errorf("error setting API Token Permission Groups for zones: %w", err))
}

if err = d.Set("user", userScopes); err != nil {
return diag.FromErr(fmt.Errorf("error setting API Token Permission Groups for user: %w", err))
}

if err = d.Set("permissions", permissionDetails); err != nil {
return diag.FromErr(fmt.Errorf("error setting API Token Permission Groups: %w", err))
}

Expand Down
Expand Up @@ -3,13 +3,14 @@ package provider
import (
"fmt"
"os"
"strconv"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestAccCloudflareApiTokenPermissionGroups(t *testing.T) {
func TestAccCloudflareApiTokenPermissionGroups_Basic(t *testing.T) {
// Temporarily unset CLOUDFLARE_API_TOKEN if it is set as the API token
// permission groups endpoint does not yet support the API tokens and it
// results in misleading state error messages.
Expand Down Expand Up @@ -39,13 +40,47 @@ func testAccCloudflareApiTokenPermissionGroups(n string) resource.TestCheckFunc
r := s.RootModule().Resources[n]
a := r.Primary.Attributes

permCount, err := strconv.Atoi(a["permissions.%"])
if err != nil {
return fmt.Errorf("failed to convert total permission count to integer")
}

if permCount < 100 {
return fmt.Errorf("total API token permission groups size is too small. expected: > 100, got: %d", permCount)
}

zonePermCount, err := strconv.Atoi(a["zone.%"])
if err != nil {
return fmt.Errorf("failed to convert zone permission count to integer")
}

if zonePermCount < 50 {
return fmt.Errorf("zone API token permission groups size is too small. expected: > 50, got: %d", zonePermCount)
}

accountPermCount, err := strconv.Atoi(a["account.%"])
if err != nil {
return fmt.Errorf("failed to convert account permission count to integer")
}

if accountPermCount < 80 {
return fmt.Errorf("account API token permission groups size is too small. expected: > 80, got: %d", accountPermCount)
}

userPermCount, err := strconv.Atoi(a["user.%"])
if err != nil {
return fmt.Errorf("failed to convert user permission count to integer")
}

if userPermCount < 5 {
return fmt.Errorf("user API token permission groups size is too small. expected: > 5, got: %d", userPermCount)
}

apiTokenReadId, ok := a["permissions.API Tokens Read"]
if !ok {
return fmt.Errorf("couldn't get 'API Tokens Read' permission ID")
}

// PermissionGroupsIDs can be found at
// https://developers.cloudflare.com/api/tokens/create/permissions
apiTokenReadIdShouldBe := "0cc3a61731504c89b99ec1be78b77aa0"

if apiTokenReadId != apiTokenReadIdShouldBe {
Expand Down
24 changes: 0 additions & 24 deletions templates/data-sources/api_token_permission_groups.md

This file was deleted.