Files
tf_provider/internal/provider/service_instance_data_source.go
T

121 lines
3.8 KiB
Go

package provider
import (
"context"
"fmt"
"strings"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
var _ datasource.DataSource = &ServiceInstanceDataSource{}
func NewServiceInstanceDataSource() datasource.DataSource {
return &ServiceInstanceDataSource{}
}
type ServiceInstanceDataSource struct {
client *NubesClient
}
type ServiceInstanceDataSourceModel struct {
ID types.String `tfsdk:"id"`
DisplayName types.String `tfsdk:"display_name"`
ServiceId types.Int64 `tfsdk:"service_id"`
ServiceName types.String `tfsdk:"service_name"`
}
func (d *ServiceInstanceDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_service_instance"
}
func (d *ServiceInstanceDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "Data source для получения UUID сервиса (Instance) по его имени (DisplayName). Позволяет использовать human-readable имена (например 's3-111805') вместо UUID.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
MarkdownDescription: "UUID найденного сервиса (instanceUid)",
Computed: true,
},
"display_name": schema.StringAttribute{
MarkdownDescription: "Имя (DisplayName) для поиска. Например 's3-111805'",
Required: true,
},
"service_id": schema.Int64Attribute{
MarkdownDescription: "ID типа сервиса для дополнительной фильтрации (например 12 для S3). Опционально.",
Optional: true,
},
"service_name": schema.StringAttribute{
MarkdownDescription: "Название типа сервиса (например 'S3 Object Storage')",
Computed: true,
},
},
}
}
func (d *ServiceInstanceDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}
client, ok := req.ProviderData.(*NubesClient)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *NubesClient, got: %T", req.ProviderData),
)
return
}
d.client = client
}
func (d *ServiceInstanceDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data ServiceInstanceDataSourceModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
displayName := data.DisplayName.ValueString()
instances, err := d.client.GetInstances(ctx)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to fetch instances list: %s", err))
return
}
var foundInstance *InstanceSummary
// Поиск по DisplayName
for _, inst := range instances {
if strings.TrimSpace(inst.DisplayName) == strings.TrimSpace(displayName) {
// Если задан service_id, проверяем и его
if !data.ServiceId.IsNull() && !data.ServiceId.IsUnknown() {
if int64(inst.ServiceId) != data.ServiceId.ValueInt64() {
continue
}
}
foundInstance = &inst
break
}
}
if foundInstance == nil {
resp.Diagnostics.AddError(
"Instance Not Found",
fmt.Sprintf("Could not find instance with DisplayName '%s'", displayName),
)
return
}
data.ID = types.StringValue(foundInstance.InstanceUid)
data.ServiceName = types.StringValue(foundInstance.Svc)
data.ServiceId = types.Int64Value(int64(foundInstance.ServiceId))
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}