teamcity/pool_data_source.go (120 lines of code) (raw):
package teamcity
import (
"context"
"errors"
"fmt"
"terraform-provider-teamcity/client"
"terraform-provider-teamcity/models"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
)
var (
_ datasource.DataSource = &poolDataSource{}
_ datasource.DataSourceWithConfigure = &poolDataSource{}
)
func NewPoolDataSource() datasource.DataSource {
return &poolDataSource{}
}
type poolDataSource struct {
client *client.Client
}
// DataSource functions implementation
// returns the full name of the data source
func (d *poolDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_pool"
}
// returns the schema of the data source
func (d *poolDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "An Agent Pool in TeamCity is a group of agents that can be associated to projects. More info [here](https://www.jetbrains.com/help/teamcity/configuring-agent-pools.html)",
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
Required: true,
},
"id": schema.Int64Attribute{
Computed: true,
},
"size": schema.Int64Attribute{
Computed: true,
MarkdownDescription: "Agents capacity for the given pool",
},
"projects": schema.SetAttribute{
Computed: true,
ElementType: types.StringType,
},
},
}
}
// returns the state of the data source
func (d *poolDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var name types.String
diags := req.Config.GetAttribute(ctx, path.Root("name"), &name)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
if name.IsUnknown() {
resp.Diagnostics.AddAttributeError(
path.Root("name"),
"Unknown Agent Pool name attribute",
"The Datasource cannot get an Agent Pool since there is an unknown configuration value for the Agent Pool name.",
)
return
}
pool, err := d.client.GetPool(name.ValueString())
if err != nil && errors.Is(err, context.DeadlineExceeded) {
resp.Diagnostics.AddError(
"Agent Pool not found: Timeout",
err.Error(),
)
return
}
if pool == nil || err != nil {
resp.Diagnostics.AddAttributeError(
path.Root("name"),
"Agent Pool not found",
"The Datasource cannot get an Agent Pool since there is no Agent Pool with the provided name.",
)
return
}
var state models.PoolDataModel
size := basetypes.NewInt64Null()
if pool.Size != nil {
size = types.Int64Value(int64(*(pool.Size)))
}
state = models.PoolDataModel{
Name: types.StringValue(string(pool.Name)),
Id: types.Int64Value(int64(*(pool.Id))),
Projects: types.SetNull(types.StringType),
Size: size,
}
if pool.Projects != nil {
elements := []attr.Value{}
for _, project := range pool.Projects.Project {
elements = append(elements, types.StringValue(*project.Id))
}
state.Projects, diags = types.SetValue(types.StringType, elements)
if diags.HasError() {
return
}
}
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
// DataSourceWithConfigure functions implementation
func (d *poolDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}
client, ok := req.ProviderData.(*client.Client)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *client.Client, got: %T.", req.ProviderData),
)
return
}
d.client = client
}