121 lines
3.8 KiB
Go
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)...)
|
|
}
|