terraform-provider-edge-con.../internal/provider/app_data_source.go
2025-11-11 14:15:52 +01:00

177 lines
5.9 KiB
Go

package provider
import (
"context"
"fmt"
"github.com/DevFW-CICD/terraform-provider-edge-connect/internal/client"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &appDataSource{}
_ datasource.DataSourceWithConfigure = &appDataSource{}
)
// NewAppDataSource is a helper function to simplify the provider implementation.
func NewAppDataSource() datasource.DataSource {
return &appDataSource{}
}
// appDataSource is the data source implementation.
type appDataSource struct {
client *client.Client
}
// appDataSourceModel maps the data source schema data.
type appDataSourceModel struct {
ID types.String `tfsdk:"id"`
Region types.String `tfsdk:"region"`
Organization types.String `tfsdk:"organization"`
Name types.String `tfsdk:"name"`
Version types.String `tfsdk:"version"`
ImageType types.String `tfsdk:"image_type"`
ImagePath types.String `tfsdk:"image_path"`
DefaultFlavor types.String `tfsdk:"default_flavor"`
Deployment types.String `tfsdk:"deployment"`
DeploymentManifest types.String `tfsdk:"deployment_manifest"`
AccessPorts types.String `tfsdk:"access_ports"`
Annotations types.String `tfsdk:"annotations"`
CreatedAt types.String `tfsdk:"created_at"`
UpdatedAt types.String `tfsdk:"updated_at"`
}
// Metadata returns the data source type name.
func (d *appDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_app"
}
// Schema defines the schema for the data source.
func (d *appDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Fetches an Edge Connect application specification.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "The unique identifier for the app (format: region/organization/name/version).",
Computed: true,
},
"region": schema.StringAttribute{
Description: "The region where the app is deployed (e.g., 'EU').",
Required: true,
},
"organization": schema.StringAttribute{
Description: "The organization that owns the app.",
Required: true,
},
"name": schema.StringAttribute{
Description: "The name of the application.",
Required: true,
},
"version": schema.StringAttribute{
Description: "The version of the application.",
Required: true,
},
"image_type": schema.StringAttribute{
Description: "The type of image (e.g., 'Docker').",
Computed: true,
},
"image_path": schema.StringAttribute{
Description: "The path to the container image.",
Computed: true,
},
"default_flavor": schema.StringAttribute{
Description: "The default flavor for the app.",
Computed: true,
},
"deployment": schema.StringAttribute{
Description: "The deployment type (e.g., 'kubernetes').",
Computed: true,
},
"deployment_manifest": schema.StringAttribute{
Description: "The Kubernetes deployment manifest (YAML).",
Computed: true,
},
"access_ports": schema.StringAttribute{
Description: "The access ports in format 'protocol:port'.",
Computed: true,
},
"annotations": schema.StringAttribute{
Description: "Annotations for the app.",
Computed: true,
},
"created_at": schema.StringAttribute{
Description: "The timestamp when the app was created.",
Computed: true,
},
"updated_at": schema.StringAttribute{
Description: "The timestamp when the app was last updated.",
Computed: true,
},
},
}
}
// Configure adds the provider configured client to the data source.
func (d *appDataSource) 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. Please report this issue to the provider developers.", req.ProviderData),
)
return
}
d.client = client
}
// Read refreshes the Terraform state with the latest data.
func (d *appDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var config appDataSourceModel
diags := req.Config.Get(ctx, &config)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
// Get app from API
app := client.App{}
app.Key.Organization = config.Organization.ValueString()
app.Key.Name = config.Name.ValueString()
app.Key.Version = config.Version.ValueString()
readApp, err := d.client.GetApp(config.Region.ValueString(), app)
if err != nil {
resp.Diagnostics.AddError(
"Error reading app",
"Could not read app: "+err.Error(),
)
return
}
// Map response to data source model
config.ID = types.StringValue(fmt.Sprintf("%s/%s/%s/%s",
config.Region.ValueString(),
readApp.Key.Organization,
readApp.Key.Name,
readApp.Key.Version))
config.ImageType = types.StringValue(readApp.ImageType)
config.ImagePath = types.StringValue(readApp.ImagePath)
config.DefaultFlavor = types.StringValue(readApp.DefaultFlavor)
config.Deployment = types.StringValue(readApp.Deployment)
config.DeploymentManifest = types.StringValue(readApp.DeploymentManifest)
config.AccessPorts = types.StringValue(readApp.AccessPorts)
config.Annotations = types.StringValue(readApp.Annotations)
config.CreatedAt = types.StringValue(readApp.CreatedAt)
config.UpdatedAt = types.StringValue(readApp.UpdatedAt)
diags = resp.State.Set(ctx, &config)
resp.Diagnostics.Append(diags...)
}