Skip to content

Commit

Permalink
Add new datasource to get current user info
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyb3r-Jak3 committed Aug 17, 2023
1 parent a473122 commit 5bd82c5
Show file tree
Hide file tree
Showing 11 changed files with 192 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .changelog/2691.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-data-source: cloudflare_user
datasource/cloudflare_user: Create new datasource to get information about current user
```
2 changes: 1 addition & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ generate-changelog:
@sh -c "'$(CURDIR)/scripts/generate-changelog.sh'"

golangci-lint:
@golangci-lint run ./$(PKG_NAME)/... --config .golintci.yml
@golangci-lint run ./internal/... --config .golintci.yml

tools:
@echo "==> Installing development tooling..."
Expand Down
41 changes: 41 additions & 0 deletions docs/data-sources/user.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
page_title: "cloudflare_user Data Source - Cloudflare"
subcategory: ""
description: |-
Use this data source to retrieve information about the currently authenticated user.
---

# cloudflare_user (Data Source)

Use this data source to retrieve information about the currently authenticated user.

## Example Usage

```terraform
data "cloudflare_user" "me" {}
data "cloudflare_api_token_permission_groups" "all" {}
resource "cloudflare_api_token" "example" {
name = "Terraform Cloud (Terraform)"
policy {
permission_groups = [
data.cloudflare_api_token_permission_groups.all.user["User Details Read"],
]
resources = {
"com.cloudflare.api.user.${data.cloudflare_user.me.id}" = "*",
}
}
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Read-Only

- `email` (String) The user's email address.
- `id` (String) The user's unique identifier.
- `username` (String) The user's username.


1 change: 1 addition & 0 deletions docs/resources/access_service_token.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ resource "cloudflare_access_service_token" "my_app" {
### Optional

- `account_id` (String) The account identifier to target for the resource. Conflicts with `zone_id`.
- `duration` (String) Length of time the service token is valid for. Available values: `8760h`, `17520h`, `43800h`, `87600h`, `forever`.
- `min_days_for_renewal` (Number) Refresh the token if terraform is run within the specified amount of days before expiration. Defaults to `0`.
- `zone_id` (String) The zone identifier to target for the resource. Conflicts with `account_id`.

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/waiting_room.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ resource "cloudflare_waiting_room" "example" {

### Optional

- `queueing_status_code` (Number) HTTP status code returned to a user while in the queue.
- `additional_routes` (Block List) A list of additional hostname and paths combination to be applied on the waiting room. (see [below for nested schema](#nestedblock--additional_routes))
- `cookie_suffix` (String) A cookie suffix to be appended to the Cloudflare waiting room cookie name.
- `custom_page_html` (String) This is a templated html file that will be rendered at the edge.
Expand All @@ -58,6 +57,7 @@ resource "cloudflare_waiting_room" "example" {
- `path` (String) The path within the host to enable the waiting room on. Defaults to `/`.
- `queue_all` (Boolean) If queue_all is true, then all traffic will be sent to the waiting room.
- `queueing_method` (String) The queueing method used by the waiting room. Available values: `fifo`, `random`, `passthrough`, `reject`. Defaults to `fifo`.
- `queueing_status_code` (Number) HTTP status code returned to a user while in the queue. Defaults to `200`.
- `session_duration` (Number) Lifetime of a cookie (in minutes) set by Cloudflare for users who get access to the origin. Defaults to `5`.
- `suspended` (Boolean) Suspends the waiting room.
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
Expand Down
15 changes: 15 additions & 0 deletions examples/data-sources/cloudflare_user/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
data "cloudflare_user" "me" {}
data "cloudflare_api_token_permission_groups" "all" {}

resource "cloudflare_api_token" "example" {
name = "Terraform Cloud (Terraform)"
policy {
permission_groups = [
data.cloudflare_api_token_permission_groups.all.user["User Details Read"],

]
resources = {
"com.cloudflare.api.user.${data.cloudflare_user.me.id}" = "*",
}
}
}
3 changes: 2 additions & 1 deletion internal/framework/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/cloudflare/terraform-provider-cloudflare/internal/framework/service/r2_bucket"
"github.com/cloudflare/terraform-provider-cloudflare/internal/framework/service/rulesets"
"github.com/cloudflare/terraform-provider-cloudflare/internal/framework/service/turnstile"
"github.com/cloudflare/terraform-provider-cloudflare/internal/framework/service/user"
"github.com/cloudflare/terraform-provider-cloudflare/internal/sdkv2provider"
"github.com/cloudflare/terraform-provider-cloudflare/internal/utils"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
Expand Down Expand Up @@ -316,7 +317,7 @@ func (p *CloudflareProvider) Resources(ctx context.Context) []func() resource.Re

func (p *CloudflareProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
// NewExampleDataSource,
user.NewDataSource,
}
}

Expand Down
60 changes: 60 additions & 0 deletions internal/framework/service/user/data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package user

import (
"context"
"fmt"
"github.com/cloudflare/cloudflare-go"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var _ datasource.DataSource = &CloudflareUserDataSource{}

func NewDataSource() datasource.DataSource {
return &CloudflareUserDataSource{}
}

type CloudflareUserDataSource struct {
client *cloudflare.API
}

func (r *CloudflareUserDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_user"
}

func (r *CloudflareUserDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*cloudflare.API)

if !ok {
resp.Diagnostics.AddError(
"unexpected resource configure type",
fmt.Sprintf("expected *cloudflare.API, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)

return
}

r.client = client
}

func (r *CloudflareUserDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data CloudflareUserDataSourceModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
user, err := r.client.UserDetails(ctx)
if err != nil {
resp.Diagnostics.AddError("unable to retrieve user details", err.Error())
return
}
data.ID = types.StringValue(user.ID)
data.Email = types.StringValue(user.Email)
data.Username = types.StringValue(user.Username)

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
32 changes: 32 additions & 0 deletions internal/framework/service/user/data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package user_test

import (
"github.com/cloudflare/terraform-provider-cloudflare/internal/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"os"
"testing"
)

func TestAccCloudflareUserDataSource(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.
if os.Getenv("CLOUDFLARE_API_TOKEN") != "" {
t.Setenv("CLOUDFLARE_API_TOKEN", "")
}

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.TestAccPreCheck(t) },
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: `data "cloudflare_user" "test" {}`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.cloudflare_user.test", "id"),
resource.TestCheckResourceAttrSet("data.cloudflare_user.test", "email"),
resource.TestCheckResourceAttrSet("data.cloudflare_user.test", "username"),
),
},
},
})
}
9 changes: 9 additions & 0 deletions internal/framework/service/user/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package user

import "github.com/hashicorp/terraform-plugin-framework/types"

type CloudflareUserDataSourceModel struct {
ID types.String `tfsdk:"id"`
Email types.String `tfsdk:"email"`
Username types.String `tfsdk:"username"`
}
27 changes: 27 additions & 0 deletions internal/framework/service/user/schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package user

import (
"context"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
)

func (r *CloudflareUserDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "Use this data source to retrieve information about the currently authenticated user.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "The user's unique identifier.",
Computed: true,
},
"email": schema.StringAttribute{
Description: "The user's email address.",
Computed: true,
},
"username": schema.StringAttribute{
Description: "The user's username.",
Computed: true,
},
},
}
}

0 comments on commit 5bd82c5

Please sign in to comment.