feat(provider): add users data-source
This commit is contained in:
parent
95834c9ad9
commit
c108605ef2
8 changed files with 329 additions and 2 deletions
|
@ -6,4 +6,5 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added provider configuration
|
- Added provider configuration.
|
||||||
|
- Added users data-source.
|
||||||
|
|
53
docs/data-sources/users.md
Normal file
53
docs/data-sources/users.md
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||||
|
page_title: "forgejo_users Data Source - terraform-provider-forgejo"
|
||||||
|
subcategory: ""
|
||||||
|
description: |-
|
||||||
|
Use this data source to retrieve information about existing forgejo users.
|
||||||
|
---
|
||||||
|
|
||||||
|
# forgejo_users (Data Source)
|
||||||
|
|
||||||
|
Use this data source to retrieve information about existing forgejo users.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```terraform
|
||||||
|
data "forgejo_users" "example" {}
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- schema generated by tfplugindocs -->
|
||||||
|
## Schema
|
||||||
|
|
||||||
|
### Read-Only
|
||||||
|
|
||||||
|
- `elements` (Attributes List) The list of users. (see [below for nested schema](#nestedatt--elements))
|
||||||
|
|
||||||
|
<a id="nestedatt--elements"></a>
|
||||||
|
### Nested Schema for `elements`
|
||||||
|
|
||||||
|
Read-Only:
|
||||||
|
|
||||||
|
- `active` (Boolean) Whether the user is active or not.
|
||||||
|
- `avatar_url` (String) The user's avatar URL.
|
||||||
|
- `created` (String) The user's creation date and time.
|
||||||
|
- `description` (String) A description string.
|
||||||
|
- `email` (String) The user's email address.
|
||||||
|
- `followers_count` (Number) The number of followers.
|
||||||
|
- `following_count` (Number) The number of followings.
|
||||||
|
- `full_name` (String) The user's full name.
|
||||||
|
- `html_url` (String) The URL to this user's Forgejo profile page.
|
||||||
|
- `id` (Number) The identifier of the user.
|
||||||
|
- `is_admin` (Boolean) Whether the user is an admin or not.
|
||||||
|
- `language` (String) The user's chosen language.
|
||||||
|
- `last_login` (String) The user's last login date and time.
|
||||||
|
- `location` (String) The user's advertised location.
|
||||||
|
- `login` (String) The login of the user.
|
||||||
|
- `login_name` (String) The user's authentication sign-in name.
|
||||||
|
- `prohibit_login` (Boolean) Whether the user is allowed to log in or not.
|
||||||
|
- `pronouns` (String) The user's advertised pronouns.
|
||||||
|
- `restricted` (Boolean) Whether the user is restricted or not.
|
||||||
|
- `source_id` (Number) The identifier of the users authentication source.
|
||||||
|
- `starred_repos_count` (Number) The number of repositoties starred by the user.
|
||||||
|
- `visibility` (String) The user's visibility option: limited, private, public.
|
||||||
|
- `website` (String) The user's advertised website.
|
1
examples/data-sources/forgejo_users/data-source.tf
Normal file
1
examples/data-sources/forgejo_users/data-source.tf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
data "forgejo_users" "example" {}
|
1
go.mod
1
go.mod
|
@ -35,6 +35,7 @@ require (
|
||||||
github.com/hashicorp/hc-install v0.9.1 // indirect
|
github.com/hashicorp/hc-install v0.9.1 // indirect
|
||||||
github.com/hashicorp/terraform-exec v0.22.0 // indirect
|
github.com/hashicorp/terraform-exec v0.22.0 // indirect
|
||||||
github.com/hashicorp/terraform-json v0.24.0 // indirect
|
github.com/hashicorp/terraform-json v0.24.0 // indirect
|
||||||
|
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 // indirect
|
||||||
github.com/hashicorp/terraform-plugin-go v0.26.0 // indirect
|
github.com/hashicorp/terraform-plugin-go v0.26.0 // indirect
|
||||||
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
|
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
|
||||||
github.com/hashicorp/terraform-registry-address v0.2.5 // indirect
|
github.com/hashicorp/terraform-registry-address v0.2.5 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -91,6 +91,8 @@ github.com/hashicorp/terraform-plugin-docs v0.21.0 h1:yoyA/Y719z9WdFJAhpUkI1jRbK
|
||||||
github.com/hashicorp/terraform-plugin-docs v0.21.0/go.mod h1:J4Wott1J2XBKZPp/NkQv7LMShJYOcrqhQ2myXBcu64s=
|
github.com/hashicorp/terraform-plugin-docs v0.21.0/go.mod h1:J4Wott1J2XBKZPp/NkQv7LMShJYOcrqhQ2myXBcu64s=
|
||||||
github.com/hashicorp/terraform-plugin-framework v1.14.1 h1:jaT1yvU/kEKEsxnbrn4ZHlgcxyIfjvZ41BLdlLk52fY=
|
github.com/hashicorp/terraform-plugin-framework v1.14.1 h1:jaT1yvU/kEKEsxnbrn4ZHlgcxyIfjvZ41BLdlLk52fY=
|
||||||
github.com/hashicorp/terraform-plugin-framework v1.14.1/go.mod h1:xNUKmvTs6ldbwTuId5euAtg37dTxuyj3LHS3uj7BHQ4=
|
github.com/hashicorp/terraform-plugin-framework v1.14.1/go.mod h1:xNUKmvTs6ldbwTuId5euAtg37dTxuyj3LHS3uj7BHQ4=
|
||||||
|
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 h1:v3DapR8gsp3EM8fKMh6up9cJUFQ2iRaFsYLP8UJnCco=
|
||||||
|
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0/go.mod h1:c3PnGE9pHBDfdEVG9t1S1C9ia5LW+gkFR0CygXlM8ak=
|
||||||
github.com/hashicorp/terraform-plugin-go v0.26.0 h1:cuIzCv4qwigug3OS7iKhpGAbZTiypAfFQmw8aE65O2M=
|
github.com/hashicorp/terraform-plugin-go v0.26.0 h1:cuIzCv4qwigug3OS7iKhpGAbZTiypAfFQmw8aE65O2M=
|
||||||
github.com/hashicorp/terraform-plugin-go v0.26.0/go.mod h1:+CXjuLDiFgqR+GcrM5a2E2Kal5t5q2jb0E3D57tTdNY=
|
github.com/hashicorp/terraform-plugin-go v0.26.0/go.mod h1:+CXjuLDiFgqR+GcrM5a2E2Kal5t5q2jb0E3D57tTdNY=
|
||||||
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
|
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
|
||||||
|
|
56
internal/client/users.go
Normal file
56
internal/client/users.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Active bool `json:"active"`
|
||||||
|
AvatarUrl string `json:"avatar_url"`
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
FollowerCount int64 `json:"followers_count"`
|
||||||
|
FollowingCount int64 `json:"following_count"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
HtmlUrl string `json:"html_url"`
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
IsAdmin bool `json:"is_admin"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
LastLogin time.Time `json:"last_login"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
LoginName string `json:"login_name"`
|
||||||
|
Login string `json:"login"`
|
||||||
|
ProhibitLogin bool `json:"prohibit_login"`
|
||||||
|
Pronouns string `json:"pronouns"`
|
||||||
|
Restricted bool `json:"restricted"`
|
||||||
|
SourceId int64 `json:"source_id"`
|
||||||
|
StarredRepoCount int64 `json:"starred_repos_count"`
|
||||||
|
Visibility string `json:"visibility"`
|
||||||
|
Website string `json:"website"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) UsersList(ctx context.Context) ([]User, error) {
|
||||||
|
type Response struct {
|
||||||
|
Data []User `json:"data"`
|
||||||
|
Ok bool `json:"ok"`
|
||||||
|
}
|
||||||
|
var response Response
|
||||||
|
query := make(url.Values)
|
||||||
|
query.Set("limit", "50")
|
||||||
|
query.Set("page", "1")
|
||||||
|
uriRef := url.URL{
|
||||||
|
Path: "api/v1/users/search",
|
||||||
|
RawQuery: query.Encode(),
|
||||||
|
}
|
||||||
|
if err := c.Send(ctx, "GET", &uriRef, nil, &response); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to search users: %w", err)
|
||||||
|
}
|
||||||
|
if !response.Ok {
|
||||||
|
return response.Data, fmt.Errorf("got a non OK status when querying users/search")
|
||||||
|
}
|
||||||
|
return response.Data, nil
|
||||||
|
}
|
|
@ -79,5 +79,7 @@ func (p *Provider) Resources(ctx context.Context) []func() resource.Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) DataSources(ctx context.Context) []func() datasource.DataSource {
|
func (p *Provider) DataSources(ctx context.Context) []func() datasource.DataSource {
|
||||||
return []func() datasource.DataSource{}
|
return []func() datasource.DataSource{
|
||||||
|
NewUsersDataSource,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
211
internal/provider/users_data_source.go
Normal file
211
internal/provider/users_data_source.go
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.adyxax.org/adyxax/terraform-provider-forgejo/internal/client"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UsersDataSource struct {
|
||||||
|
client *client.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ datasource.DataSource = &UsersDataSource{} // Ensure provider defined types fully satisfy framework interfaces
|
||||||
|
func NewUsersDataSource() datasource.DataSource {
|
||||||
|
return &UsersDataSource{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type UsersDataSourceModel struct {
|
||||||
|
Elements []UserDataSourceModel `tfsdk:"elements"`
|
||||||
|
}
|
||||||
|
type UserDataSourceModel struct {
|
||||||
|
Active types.Bool `tfsdk:"active"`
|
||||||
|
AvatarUrl types.String `tfsdk:"avatar_url"`
|
||||||
|
Created timetypes.RFC3339 `tfsdk:"created"`
|
||||||
|
Description types.String `tfsdk:"description"`
|
||||||
|
Email types.String `tfsdk:"email"`
|
||||||
|
FollowerCount types.Int64 `tfsdk:"followers_count"`
|
||||||
|
FollowingCount types.Int64 `tfsdk:"following_count"`
|
||||||
|
FullName types.String `tfsdk:"full_name"`
|
||||||
|
HtmlUrl types.String `tfsdk:"html_url"`
|
||||||
|
Id types.Int64 `tfsdk:"id"`
|
||||||
|
IsAdmin types.Bool `tfsdk:"is_admin"`
|
||||||
|
Language types.String `tfsdk:"language"`
|
||||||
|
LastLogin timetypes.RFC3339 `tfsdk:"last_login"`
|
||||||
|
Location types.String `tfsdk:"location"`
|
||||||
|
LoginName types.String `tfsdk:"login_name"`
|
||||||
|
Login types.String `tfsdk:"login"`
|
||||||
|
ProhibitLogin types.Bool `tfsdk:"prohibit_login"`
|
||||||
|
Pronouns types.String `tfsdk:"pronouns"`
|
||||||
|
Restricted types.Bool `tfsdk:"restricted"`
|
||||||
|
SourceId types.Int64 `tfsdk:"source_id"`
|
||||||
|
StarredRepoCount types.Int64 `tfsdk:"starred_repos_count"`
|
||||||
|
Visibility types.String `tfsdk:"visibility"`
|
||||||
|
Website types.String `tfsdk:"website"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *UsersDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
||||||
|
resp.TypeName = req.ProviderTypeName + "_users"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *UsersDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||||
|
resp.Schema = schema.Schema{
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"elements": schema.ListNestedAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The list of users.",
|
||||||
|
NestedObject: schema.NestedAttributeObject{
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"active": schema.BoolAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "Whether the user is active or not.",
|
||||||
|
},
|
||||||
|
"avatar_url": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The user's avatar URL.",
|
||||||
|
},
|
||||||
|
"created": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
CustomType: timetypes.RFC3339Type{},
|
||||||
|
MarkdownDescription: "The user's creation date and time.",
|
||||||
|
},
|
||||||
|
"description": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "A description string.",
|
||||||
|
},
|
||||||
|
"email": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The user's email address.",
|
||||||
|
},
|
||||||
|
"followers_count": schema.Int64Attribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The number of followers.",
|
||||||
|
},
|
||||||
|
"following_count": schema.Int64Attribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The number of followings.",
|
||||||
|
},
|
||||||
|
"full_name": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The user's full name.",
|
||||||
|
},
|
||||||
|
"html_url": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The URL to this user's Forgejo profile page.",
|
||||||
|
},
|
||||||
|
"id": schema.Int64Attribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The identifier of the user.",
|
||||||
|
},
|
||||||
|
"is_admin": schema.BoolAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "Whether the user is an admin or not.",
|
||||||
|
},
|
||||||
|
"language": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The user's chosen language.",
|
||||||
|
},
|
||||||
|
"last_login": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
CustomType: timetypes.RFC3339Type{},
|
||||||
|
MarkdownDescription: "The user's last login date and time.",
|
||||||
|
},
|
||||||
|
"location": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The user's advertised location.",
|
||||||
|
},
|
||||||
|
"login_name": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The user's authentication sign-in name.",
|
||||||
|
},
|
||||||
|
"login": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The login of the user.",
|
||||||
|
},
|
||||||
|
"prohibit_login": schema.BoolAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "Whether the user is allowed to log in or not.",
|
||||||
|
},
|
||||||
|
"pronouns": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The user's advertised pronouns.",
|
||||||
|
},
|
||||||
|
"restricted": schema.BoolAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "Whether the user is restricted or not.",
|
||||||
|
},
|
||||||
|
"source_id": schema.Int64Attribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The identifier of the users authentication source.",
|
||||||
|
},
|
||||||
|
"starred_repos_count": schema.Int64Attribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The number of repositoties starred by the user.",
|
||||||
|
},
|
||||||
|
"visibility": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The user's visibility option: limited, private, public.",
|
||||||
|
},
|
||||||
|
"website": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
MarkdownDescription: "The user's advertised website.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MarkdownDescription: "Use this data source to retrieve information about existing forgejo users.",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *UsersDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||||
|
d.client, _ = req.ProviderData.(*client.Client)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *UsersDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||||
|
var data UsersDataSourceModel
|
||||||
|
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
users, err := d.client.UsersList(ctx)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError("ListUsers", fmt.Sprintf("Unable to list users, got error: %s", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
userList := make([]UserDataSourceModel, len(users))
|
||||||
|
for i, user := range users {
|
||||||
|
userList[i] = UserDataSourceModel{
|
||||||
|
Active: types.BoolValue(user.Active),
|
||||||
|
AvatarUrl: types.StringValue(user.AvatarUrl),
|
||||||
|
Created: timetypes.NewRFC3339TimeValue(user.Created),
|
||||||
|
Description: types.StringValue(user.Description),
|
||||||
|
Email: types.StringValue(user.Email),
|
||||||
|
FollowerCount: types.Int64Value(user.FollowerCount),
|
||||||
|
FollowingCount: types.Int64Value(user.FollowingCount),
|
||||||
|
FullName: types.StringValue(user.FullName),
|
||||||
|
HtmlUrl: types.StringValue(user.HtmlUrl),
|
||||||
|
Id: types.Int64Value(user.Id),
|
||||||
|
IsAdmin: types.BoolValue(user.IsAdmin),
|
||||||
|
Language: types.StringValue(user.Language),
|
||||||
|
LastLogin: timetypes.NewRFC3339TimeValue(user.LastLogin),
|
||||||
|
Location: types.StringValue(user.Location),
|
||||||
|
LoginName: types.StringValue(user.LoginName),
|
||||||
|
Login: types.StringValue(user.Login),
|
||||||
|
ProhibitLogin: types.BoolValue(user.ProhibitLogin),
|
||||||
|
Pronouns: types.StringValue(user.Pronouns),
|
||||||
|
Restricted: types.BoolValue(user.Restricted),
|
||||||
|
SourceId: types.Int64Value(user.SourceId),
|
||||||
|
StarredRepoCount: types.Int64Value(user.StarredRepoCount),
|
||||||
|
Visibility: types.StringValue(user.Visibility),
|
||||||
|
Website: types.StringValue(user.Website),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.Elements = userList
|
||||||
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue