updated app resource

This commit is contained in:
Manuel Ganter 2025-11-11 16:20:36 +01:00
parent 728b27146e
commit 6c7a34d68a
No known key found for this signature in database
2 changed files with 88 additions and 132 deletions

View file

@ -17,26 +17,24 @@ resource "edge-connect_app" "edge_app_demo" {
manifest = file("${path.module}/k8s-deployment.yaml") manifest = file("${path.module}/k8s-deployment.yaml")
infra_template { region = "US"
region = "US" cloudlet_org = "TelekomOp"
cloudlet_org = "TelekomOp" cloudlet_name = "gardener-shepherd-test"
cloudlet_name = "gardener-shepherd-test" flavor_name = "default"
flavor_name = "default"
network { network {
outbound_connections { outbound_connections {
protocol = "tcp" protocol = "tcp"
port_range_min = 80 port_range_min = 80
port_range_max = 80 port_range_max = 80
remote_cidr = "0.0.0.0/0" remote_cidr = "0.0.0.0/0"
} }
outbound_connections { outbound_connections {
protocol = "tcp" protocol = "tcp"
port_range_min = 443 port_range_min = 443
port_range_max = 443 port_range_max = 443
remote_cidr = "0.0.0.0/0" remote_cidr = "0.0.0.0/0"
}
} }
} }
} }

View file

@ -27,20 +27,16 @@ type AppResource struct {
} }
type AppResourceModel struct { type AppResourceModel struct {
Id types.String `tfsdk:"id"` Id types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"` Name types.String `tfsdk:"name"`
AppVersion types.String `tfsdk:"app_version"` AppVersion types.String `tfsdk:"app_version"`
Organization types.String `tfsdk:"organization"` Organization types.String `tfsdk:"organization"`
Manifest types.String `tfsdk:"manifest"` Manifest types.String `tfsdk:"manifest"`
InfraTemplate []InfraTemplateModel `tfsdk:"infra_template"` Region types.String `tfsdk:"region"`
} CloudletOrg types.String `tfsdk:"cloudlet_org"`
CloudletName types.String `tfsdk:"cloudlet_name"`
type InfraTemplateModel struct { FlavorName types.String `tfsdk:"flavor_name"`
Region types.String `tfsdk:"region"` Network *NetworkModel `tfsdk:"network"`
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 { type NetworkModel struct {
@ -86,54 +82,46 @@ func (r *AppResource) Schema(ctx context.Context, req resource.SchemaRequest, re
MarkdownDescription: "Kubernetes manifest YAML content", MarkdownDescription: "Kubernetes manifest YAML content",
Required: true, Required: true,
}, },
"infra_template": schema.ListNestedAttribute{ "region": schema.StringAttribute{
MarkdownDescription: "Infrastructure template configurations", MarkdownDescription: "Region (e.g., US, EU)",
Required: true, Required: true,
NestedObject: schema.NestedAttributeObject{ },
Attributes: map[string]schema.Attribute{ "cloudlet_org": schema.StringAttribute{
"region": schema.StringAttribute{ MarkdownDescription: "Cloudlet organization",
MarkdownDescription: "Region (e.g., US, EU)", Required: true,
Required: true, },
}, "cloudlet_name": schema.StringAttribute{
"cloudlet_org": schema.StringAttribute{ MarkdownDescription: "Cloudlet name",
MarkdownDescription: "Cloudlet organization", Required: true,
Required: true, },
}, "flavor_name": schema.StringAttribute{
"cloudlet_name": schema.StringAttribute{ MarkdownDescription: "Flavor name",
MarkdownDescription: "Cloudlet name", Required: true,
Required: true, },
}, "network": schema.SingleNestedAttribute{
"flavor_name": schema.StringAttribute{ MarkdownDescription: "Network configuration",
MarkdownDescription: "Flavor name", Optional: true,
Required: true, Attributes: map[string]schema.Attribute{
}, "outbound_connections": schema.ListNestedAttribute{
"network": schema.SingleNestedAttribute{ MarkdownDescription: "Outbound connection rules",
MarkdownDescription: "Network configuration", Optional: true,
Optional: true, NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{ Attributes: map[string]schema.Attribute{
"outbound_connections": schema.ListNestedAttribute{ "protocol": schema.StringAttribute{
MarkdownDescription: "Outbound connection rules", MarkdownDescription: "Protocol (tcp, udp, icmp)",
Optional: true, Required: true,
NestedObject: schema.NestedAttributeObject{ },
Attributes: map[string]schema.Attribute{ "port_range_min": schema.Int64Attribute{
"protocol": schema.StringAttribute{ MarkdownDescription: "Minimum port number",
MarkdownDescription: "Protocol (tcp, udp, icmp)", Required: true,
Required: true, },
}, "port_range_max": schema.Int64Attribute{
"port_range_min": schema.Int64Attribute{ MarkdownDescription: "Maximum port number",
MarkdownDescription: "Minimum port number", Required: true,
Required: true, },
}, "remote_cidr": schema.StringAttribute{
"port_range_max": schema.Int64Attribute{ MarkdownDescription: "Remote CIDR (e.g., 0.0.0.0/0)",
MarkdownDescription: "Maximum port number", Required: true,
Required: true,
},
"remote_cidr": schema.StringAttribute{
MarkdownDescription: "Remote CIDR (e.g., 0.0.0.0/0)",
Required: true,
},
},
},
}, },
}, },
}, },
@ -172,29 +160,21 @@ func (r *AppResource) Create(ctx context.Context, req resource.CreateRequest, re
return return
} }
// Build outbound connections from all infra templates // Build outbound connections from network
var outboundConnections []edgeclient.SecurityRule var outboundConnections []edgeclient.SecurityRule
for _, infraTemplate := range data.InfraTemplate { if data.Network != nil && len(data.Network.OutboundConnections) > 0 {
if infraTemplate.Network != nil && len(infraTemplate.Network.OutboundConnections) > 0 { for _, conn := range data.Network.OutboundConnections {
for _, conn := range infraTemplate.Network.OutboundConnections { outboundConnections = append(outboundConnections, edgeclient.SecurityRule{
outboundConnections = append(outboundConnections, edgeclient.SecurityRule{ Protocol: conn.Protocol.ValueString(),
Protocol: conn.Protocol.ValueString(), PortRangeMin: int(conn.PortRangeMin.ValueInt64()),
PortRangeMin: int(conn.PortRangeMin.ValueInt64()), PortRangeMax: int(conn.PortRangeMax.ValueInt64()),
PortRangeMax: int(conn.PortRangeMax.ValueInt64()), RemoteCIDR: conn.RemoteCIDR.ValueString(),
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{ appInput := &edgeclient.NewAppInput{
Region: region, Region: data.Region.ValueString(),
App: edgeclient.App{ App: edgeclient.App{
Key: edgeclient.AppKey{ Key: edgeclient.AppKey{
Organization: data.Organization.ValueString(), Organization: data.Organization.ValueString(),
@ -236,13 +216,7 @@ func (r *AppResource) Read(ctx context.Context, req resource.ReadRequest, resp *
Version: data.AppVersion.ValueString(), Version: data.AppVersion.ValueString(),
} }
// Use the first infra template's region for the query app, err := r.client.ShowApp(ctx, appKey, data.Region.ValueString())
region := "default"
if len(data.InfraTemplate) > 0 {
region = data.InfraTemplate[0].Region.ValueString()
}
app, err := r.client.ShowApp(ctx, appKey, region)
if err != nil { if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read app %s, got error: %s", data.Id.ValueString(), err)) resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read app %s, got error: %s", data.Id.ValueString(), err))
return return
@ -254,10 +228,8 @@ func (r *AppResource) Read(ctx context.Context, req resource.ReadRequest, resp *
data.Organization = types.StringValue(app.Key.Organization) data.Organization = types.StringValue(app.Key.Organization)
data.Manifest = types.StringValue(app.DeploymentManifest) data.Manifest = types.StringValue(app.DeploymentManifest)
// Reconstruct infra templates from outbound connections if available // Note: The API returns RequiredOutboundConnections but not the full infrastructure details
// Note: The API returns RequiredOutboundConnections but not the full infra template details // We preserve the existing region, cloudlet, flavor, and network from state since the API doesn't return them
// 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)...) resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
} }
@ -271,29 +243,21 @@ func (r *AppResource) Update(ctx context.Context, req resource.UpdateRequest, re
return return
} }
// Build outbound connections from all infra templates // Build outbound connections from network
var outboundConnections []edgeclient.SecurityRule var outboundConnections []edgeclient.SecurityRule
for _, infraTemplate := range data.InfraTemplate { if data.Network != nil && len(data.Network.OutboundConnections) > 0 {
if infraTemplate.Network != nil && len(infraTemplate.Network.OutboundConnections) > 0 { for _, conn := range data.Network.OutboundConnections {
for _, conn := range infraTemplate.Network.OutboundConnections { outboundConnections = append(outboundConnections, edgeclient.SecurityRule{
outboundConnections = append(outboundConnections, edgeclient.SecurityRule{ Protocol: conn.Protocol.ValueString(),
Protocol: conn.Protocol.ValueString(), PortRangeMin: int(conn.PortRangeMin.ValueInt64()),
PortRangeMin: int(conn.PortRangeMin.ValueInt64()), PortRangeMax: int(conn.PortRangeMax.ValueInt64()),
PortRangeMax: int(conn.PortRangeMax.ValueInt64()), RemoteCIDR: conn.RemoteCIDR.ValueString(),
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{ updateInput := &edgeclient.UpdateAppInput{
Region: region, Region: data.Region.ValueString(),
App: edgeclient.App{ App: edgeclient.App{
Key: edgeclient.AppKey{ Key: edgeclient.AppKey{
Organization: data.Organization.ValueString(), Organization: data.Organization.ValueString(),
@ -331,13 +295,7 @@ func (r *AppResource) Delete(ctx context.Context, req resource.DeleteRequest, re
Version: data.AppVersion.ValueString(), Version: data.AppVersion.ValueString(),
} }
// Use the first infra template's region for deletion err := r.client.DeleteApp(ctx, appKey, data.Region.ValueString())
region := "default"
if len(data.InfraTemplate) > 0 {
region = data.InfraTemplate[0].Region.ValueString()
}
err := r.client.DeleteApp(ctx, appKey, region)
if err != nil { if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete app, got error: %s", err)) resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete app, got error: %s", err))
return return