updated tf strcutrure

This commit is contained in:
Manuel Ganter 2025-11-11 16:12:54 +01:00
parent ff81bf738a
commit 728b27146e
No known key found for this signature in database
3 changed files with 253 additions and 45 deletions

View file

@ -27,11 +27,31 @@ type AppResource struct {
}
type AppResourceModel struct {
Id types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Version types.String `tfsdk:"version"`
Status types.String `tfsdk:"status"`
Id types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
AppVersion types.String `tfsdk:"app_version"`
Organization types.String `tfsdk:"organization"`
Manifest types.String `tfsdk:"manifest"`
InfraTemplate []InfraTemplateModel `tfsdk:"infra_template"`
}
type InfraTemplateModel struct {
Region types.String `tfsdk:"region"`
CloudletOrg types.String `tfsdk:"cloudlet_org"`
CloudletName types.String `tfsdk:"cloudlet_name"`
FlavorName types.String `tfsdk:"flavor_name"`
Network *NetworkModel `tfsdk:"network"`
}
type NetworkModel struct {
OutboundConnections []OutboundConnectionModel `tfsdk:"outbound_connections"`
}
type OutboundConnectionModel struct {
Protocol types.String `tfsdk:"protocol"`
PortRangeMin types.Int64 `tfsdk:"port_range_min"`
PortRangeMax types.Int64 `tfsdk:"port_range_max"`
RemoteCIDR types.String `tfsdk:"remote_cidr"`
}
func (r *AppResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
@ -40,7 +60,7 @@ func (r *AppResource) Metadata(ctx context.Context, req resource.MetadataRequest
func (r *AppResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "App resource",
MarkdownDescription: "EdgeConnect App deployment resource",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
@ -54,17 +74,71 @@ func (r *AppResource) Schema(ctx context.Context, req resource.SchemaRequest, re
MarkdownDescription: "App name",
Required: true,
},
"description": schema.StringAttribute{
MarkdownDescription: "App description",
Optional: true,
},
"version": schema.StringAttribute{
"app_version": schema.StringAttribute{
MarkdownDescription: "App version",
Optional: true,
Required: true,
},
"status": schema.StringAttribute{
MarkdownDescription: "App status",
Computed: true,
"organization": schema.StringAttribute{
MarkdownDescription: "Organization name",
Required: true,
},
"manifest": schema.StringAttribute{
MarkdownDescription: "Kubernetes manifest YAML content",
Required: true,
},
"infra_template": schema.ListNestedAttribute{
MarkdownDescription: "Infrastructure template configurations",
Required: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"region": schema.StringAttribute{
MarkdownDescription: "Region (e.g., US, EU)",
Required: true,
},
"cloudlet_org": schema.StringAttribute{
MarkdownDescription: "Cloudlet organization",
Required: true,
},
"cloudlet_name": schema.StringAttribute{
MarkdownDescription: "Cloudlet name",
Required: true,
},
"flavor_name": schema.StringAttribute{
MarkdownDescription: "Flavor name",
Required: true,
},
"network": schema.SingleNestedAttribute{
MarkdownDescription: "Network configuration",
Optional: true,
Attributes: map[string]schema.Attribute{
"outbound_connections": schema.ListNestedAttribute{
MarkdownDescription: "Outbound connection rules",
Optional: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"protocol": schema.StringAttribute{
MarkdownDescription: "Protocol (tcp, udp, icmp)",
Required: true,
},
"port_range_min": schema.Int64Attribute{
MarkdownDescription: "Minimum port number",
Required: true,
},
"port_range_max": schema.Int64Attribute{
MarkdownDescription: "Maximum port number",
Required: true,
},
"remote_cidr": schema.StringAttribute{
MarkdownDescription: "Remote CIDR (e.g., 0.0.0.0/0)",
Required: true,
},
},
},
},
},
},
},
},
},
},
}
@ -98,17 +172,39 @@ func (r *AppResource) Create(ctx context.Context, req resource.CreateRequest, re
return
}
// Build outbound connections from all infra templates
var outboundConnections []edgeclient.SecurityRule
for _, infraTemplate := range data.InfraTemplate {
if infraTemplate.Network != nil && len(infraTemplate.Network.OutboundConnections) > 0 {
for _, conn := range infraTemplate.Network.OutboundConnections {
outboundConnections = append(outboundConnections, edgeclient.SecurityRule{
Protocol: conn.Protocol.ValueString(),
PortRangeMin: int(conn.PortRangeMin.ValueInt64()),
PortRangeMax: int(conn.PortRangeMax.ValueInt64()),
RemoteCIDR: conn.RemoteCIDR.ValueString(),
})
}
}
}
// Use the first infra template's region as the deployment region
region := "default"
if len(data.InfraTemplate) > 0 {
region = data.InfraTemplate[0].Region.ValueString()
}
appInput := &edgeclient.NewAppInput{
Region: "default",
Region: region,
App: edgeclient.App{
Key: edgeclient.AppKey{
Organization: "default",
Organization: data.Organization.ValueString(),
Name: data.Name.ValueString(),
Version: data.Version.ValueString(),
Version: data.AppVersion.ValueString(),
},
Deployment: "kubernetes",
ImageType: "docker",
ImagePath: "nginx:latest",
Deployment: "kubernetes",
ImageType: "docker",
DeploymentManifest: data.Manifest.ValueString(),
RequiredOutboundConnections: outboundConnections,
},
}
@ -119,10 +215,6 @@ func (r *AppResource) Create(ctx context.Context, req resource.CreateRequest, re
}
data.Id = types.StringValue(appInput.App.Key.Name)
data.Name = types.StringValue(appInput.App.Key.Name)
data.Description = types.StringValue("")
data.Version = types.StringValue(appInput.App.Key.Version)
data.Status = types.StringValue("created")
tflog.Trace(ctx, "created an app resource")
@ -139,21 +231,33 @@ func (r *AppResource) Read(ctx context.Context, req resource.ReadRequest, resp *
}
appKey := edgeclient.AppKey{
Organization: "default",
Organization: data.Organization.ValueString(),
Name: data.Id.ValueString(),
Version: data.Version.ValueString(),
Version: data.AppVersion.ValueString(),
}
app, err := r.client.ShowApp(ctx, appKey, "default")
// Use the first infra template's region for the query
region := "default"
if len(data.InfraTemplate) > 0 {
region = data.InfraTemplate[0].Region.ValueString()
}
app, err := r.client.ShowApp(ctx, appKey, region)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read app %s, got error: %s", data.Id.ValueString(), err))
return
}
// Update state from API response
data.Name = types.StringValue(app.Key.Name)
data.Description = types.StringValue("")
data.Version = types.StringValue(app.Key.Version)
data.Status = types.StringValue("")
data.AppVersion = types.StringValue(app.Key.Version)
data.Organization = types.StringValue(app.Key.Organization)
data.Manifest = types.StringValue(app.DeploymentManifest)
// Reconstruct infra templates from outbound connections if available
// Note: The API returns RequiredOutboundConnections but not the full infra template details
// We preserve the existing infra template from state since the API doesn't return it
// The outbound connections can be compared if needed
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
@ -167,17 +271,39 @@ func (r *AppResource) Update(ctx context.Context, req resource.UpdateRequest, re
return
}
// Build outbound connections from all infra templates
var outboundConnections []edgeclient.SecurityRule
for _, infraTemplate := range data.InfraTemplate {
if infraTemplate.Network != nil && len(infraTemplate.Network.OutboundConnections) > 0 {
for _, conn := range infraTemplate.Network.OutboundConnections {
outboundConnections = append(outboundConnections, edgeclient.SecurityRule{
Protocol: conn.Protocol.ValueString(),
PortRangeMin: int(conn.PortRangeMin.ValueInt64()),
PortRangeMax: int(conn.PortRangeMax.ValueInt64()),
RemoteCIDR: conn.RemoteCIDR.ValueString(),
})
}
}
}
// Use the first infra template's region as the deployment region
region := "default"
if len(data.InfraTemplate) > 0 {
region = data.InfraTemplate[0].Region.ValueString()
}
updateInput := &edgeclient.UpdateAppInput{
Region: "default",
Region: region,
App: edgeclient.App{
Key: edgeclient.AppKey{
Organization: "default",
Organization: data.Organization.ValueString(),
Name: data.Name.ValueString(),
Version: data.Version.ValueString(),
Version: data.AppVersion.ValueString(),
},
Deployment: "kubernetes",
ImageType: "docker",
ImagePath: "nginx:latest",
Deployment: "kubernetes",
ImageType: "docker",
DeploymentManifest: data.Manifest.ValueString(),
RequiredOutboundConnections: outboundConnections,
},
}
@ -187,11 +313,6 @@ func (r *AppResource) Update(ctx context.Context, req resource.UpdateRequest, re
return
}
data.Name = types.StringValue(updateInput.App.Key.Name)
data.Description = types.StringValue("")
data.Version = types.StringValue(updateInput.App.Key.Version)
data.Status = types.StringValue("updated")
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
@ -205,12 +326,18 @@ func (r *AppResource) Delete(ctx context.Context, req resource.DeleteRequest, re
}
appKey := edgeclient.AppKey{
Organization: "default",
Organization: data.Organization.ValueString(),
Name: data.Id.ValueString(),
Version: data.Version.ValueString(),
Version: data.AppVersion.ValueString(),
}
err := r.client.DeleteApp(ctx, appKey, "default")
// Use the first infra template's region for deletion
region := "default"
if len(data.InfraTemplate) > 0 {
region = data.InfraTemplate[0].Region.ValueString()
}
err := r.client.DeleteApp(ctx, appKey, region)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete app, got error: %s", err))
return