Monitoring Logik + Container View Fix
This commit is contained in:
@@ -20,9 +20,11 @@ public class ContainerController : Controller
|
||||
public async Task<IActionResult> Overview()
|
||||
{
|
||||
var containers = await _context.Containers.ToListAsync();
|
||||
var servers = await _context.Servers.ToListAsync();
|
||||
|
||||
var viewModel = new ContainerOverviewViewModel
|
||||
{
|
||||
Servers = servers,
|
||||
Containers = containers
|
||||
};
|
||||
|
||||
|
@@ -39,16 +39,42 @@ public class MetricDto
|
||||
{
|
||||
// Server Identity
|
||||
[Required]
|
||||
public int Id { get; set; }
|
||||
public int ServerId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string? IpAddress { get; set; }
|
||||
|
||||
// Metrics
|
||||
// CPU Auslastung, CPU Temperatur
|
||||
// GPU Auslastung, GPU Temperatur
|
||||
// RAM Auslastung
|
||||
// Disks?
|
||||
// Hardware Metrics
|
||||
// CPU
|
||||
public double CPU_Load { get; set; } // %
|
||||
|
||||
public double CPU_Temp { get; set; } // deg C
|
||||
|
||||
// GPU
|
||||
public double GPU_Load { get; set; } // %
|
||||
|
||||
public double GPU_Temp { get; set; } // deg C
|
||||
|
||||
public double GPU_Vram_Size { get; set; } // GB
|
||||
|
||||
public double GPU_Vram_Usage { get; set; } // %
|
||||
|
||||
// RAM
|
||||
public double RAM_Size { get; set; } // GB
|
||||
|
||||
public double RAM_Load { get; set; } // %
|
||||
|
||||
// Disks
|
||||
public double DISK_Size { get; set; } // GB
|
||||
|
||||
public double DISK_Usage { get; set; } // %
|
||||
|
||||
public double DISK_Temp { get; set; } // deg C
|
||||
|
||||
// Network
|
||||
public double NET_In { get; set; } // Bit
|
||||
|
||||
public double NET_Out { get; set; } // Bit
|
||||
}
|
||||
|
||||
|
||||
@@ -128,18 +154,64 @@ public class MonitoringController : Controller
|
||||
// Server in Datenbank finden
|
||||
var server = await _context.Servers
|
||||
.FirstOrDefaultAsync(s => s.IPAddress == dto.IpAddress);
|
||||
|
||||
|
||||
if (server != null)
|
||||
{
|
||||
// TODO: Serverdaten in Datenbank eintragen
|
||||
var NewMetric = new Metric
|
||||
{
|
||||
Timestamp = DateTime.UtcNow,
|
||||
ServerId = dto.ServerId,
|
||||
CPU_Load = dto.CPU_Load,
|
||||
CPU_Temp = dto.CPU_Temp,
|
||||
GPU_Load = dto.GPU_Load,
|
||||
GPU_Temp = dto.GPU_Temp,
|
||||
GPU_Vram_Size = dto.GPU_Vram_Size,
|
||||
GPU_Vram_Usage = dto.GPU_Vram_Usage,
|
||||
RAM_Load = dto.RAM_Load,
|
||||
RAM_Size = dto.RAM_Size,
|
||||
DISK_Size = dto.RAM_Size,
|
||||
DISK_Usage = dto.DISK_Usage,
|
||||
DISK_Temp = dto.DISK_Temp,
|
||||
NET_In = dto.NET_In,
|
||||
NET_Out = dto.NET_Out
|
||||
};
|
||||
try
|
||||
{
|
||||
_context.Metrics.Add(NewMetric);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Success
|
||||
_logger.LogInformation("Monitoring-Daten für '{server}' empfangen", server.Name);
|
||||
return Ok();
|
||||
_logger.LogInformation("Monitoring-Daten für '{server}' empfangen", server.Name);
|
||||
return Ok();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Alert triggern
|
||||
|
||||
_logger.LogError("Metric für {server} konnte nicht in Datenbank geschrieben werden.", server.Name);
|
||||
return BadRequest();
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogError("Kein Server für eingegangenen Monitoring-Payload gefunden");
|
||||
return NotFound("No Matching Server found.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Durchschnittliche Werte Berechnen
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> CalculateMedian(string Metric, int HoursToMonitor, int ServerId)
|
||||
{
|
||||
// Aktuelle Zeit - X Stunden = letzter Wert, der berücksichtigt werden soll
|
||||
DateTime TimeToMonitor = DateTime.Now.AddHours(-HoursToMonitor);
|
||||
|
||||
// Alle Metrics von Server "ServerId" finden, die in der festgelegten Zeitspanne liegen
|
||||
var MetricsInTimeFrame = await _context.Metrics
|
||||
.Where(e => e.Timestamp >= TimeToMonitor && e.ServerId == ServerId)
|
||||
.ToListAsync();
|
||||
|
||||
// return Action (MetricsInTimeFrame)
|
||||
|
||||
return NotFound();
|
||||
}
|
||||
}
|
@@ -153,7 +153,7 @@ public class ServerController : Controller
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return PartialView("_ServerCard", servers); // korrekt
|
||||
return PartialView("_ServerCard", servers);
|
||||
}
|
||||
|
||||
|
||||
|
332
Watcher/Migrations/20250710090920_container-attribute.Designer.cs
generated
Normal file
332
Watcher/Migrations/20250710090920_container-attribute.Designer.cs
generated
Normal file
@@ -0,0 +1,332 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Watcher.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Watcher.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDbContext))]
|
||||
[Migration("20250710090920_container-attribute")]
|
||||
partial class containerattribute
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.6");
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.Container", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("ExposedPort")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Health")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("HostServerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Image")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("InternalPort")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsRunning")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("TagId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("HostServerId");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.HasIndex("TagId");
|
||||
|
||||
b.ToTable("Containers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.Image", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Tag")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Images");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.LogEvent", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ContainerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Level")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Timestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ContainerId");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("LogEvents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.Metric", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<double>("CPU_Load")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("CPU_Temp")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("DISK_Size")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("DISK_Temp")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("DISK_Usage")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("GPU_Load")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("GPU_Temp")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("GPU_Vram_Size")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("GPU_Vram_Usage")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("NET_In")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("NET_Out")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("RAM_Load")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<double>("RAM_Size")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Timestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Metrics");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.Server", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CpuCores")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CpuType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GpuType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("IPAddress")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsOnline")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsVerified")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("LastSeen")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("RamSize")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<int?>("TagId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TagId");
|
||||
|
||||
b.ToTable("Servers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.Tag", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Tags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("IdentityProvider")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("LastLogin")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("OIDC_Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.Container", b =>
|
||||
{
|
||||
b.HasOne("Watcher.Models.Server", "HostServer")
|
||||
.WithMany()
|
||||
.HasForeignKey("HostServerId");
|
||||
|
||||
b.HasOne("Watcher.Models.Image", null)
|
||||
.WithMany("Containers")
|
||||
.HasForeignKey("ImageId");
|
||||
|
||||
b.HasOne("Watcher.Models.Tag", null)
|
||||
.WithMany("Containers")
|
||||
.HasForeignKey("TagId");
|
||||
|
||||
b.Navigation("HostServer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.LogEvent", b =>
|
||||
{
|
||||
b.HasOne("Watcher.Models.Container", "Container")
|
||||
.WithMany()
|
||||
.HasForeignKey("ContainerId");
|
||||
|
||||
b.HasOne("Watcher.Models.Server", "Server")
|
||||
.WithMany()
|
||||
.HasForeignKey("ServerId");
|
||||
|
||||
b.Navigation("Container");
|
||||
|
||||
b.Navigation("Server");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.Server", b =>
|
||||
{
|
||||
b.HasOne("Watcher.Models.Tag", null)
|
||||
.WithMany("Servers")
|
||||
.HasForeignKey("TagId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.Image", b =>
|
||||
{
|
||||
b.Navigation("Containers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.Tag", b =>
|
||||
{
|
||||
b.Navigation("Containers");
|
||||
|
||||
b.Navigation("Servers");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
119
Watcher/Migrations/20250710090920_container-attribute.cs
Normal file
119
Watcher/Migrations/20250710090920_container-attribute.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Watcher.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class containerattribute : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Hostname",
|
||||
table: "Containers");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "Type",
|
||||
table: "Containers",
|
||||
newName: "Health");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Containers",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "ExposedPort",
|
||||
table: "Containers",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "HostServerId",
|
||||
table: "Containers",
|
||||
type: "INTEGER",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Image",
|
||||
table: "Containers",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "InternalPort",
|
||||
table: "Containers",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Containers_HostServerId",
|
||||
table: "Containers",
|
||||
column: "HostServerId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Containers_Servers_HostServerId",
|
||||
table: "Containers",
|
||||
column: "HostServerId",
|
||||
principalTable: "Servers",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Containers_Servers_HostServerId",
|
||||
table: "Containers");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Containers_HostServerId",
|
||||
table: "Containers");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ExposedPort",
|
||||
table: "Containers");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "HostServerId",
|
||||
table: "Containers");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Image",
|
||||
table: "Containers");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "InternalPort",
|
||||
table: "Containers");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "Health",
|
||||
table: "Containers",
|
||||
newName: "Type");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Containers",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: "",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Hostname",
|
||||
table: "Containers",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
}
|
||||
}
|
@@ -26,18 +26,29 @@ namespace Watcher.Migrations
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Hostname")
|
||||
b.Property<int>("ExposedPort")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Health")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("HostServerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Image")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("InternalPort")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsRunning")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Status")
|
||||
@@ -47,12 +58,10 @@ namespace Watcher.Migrations
|
||||
b.Property<int?>("TagId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("HostServerId");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.HasIndex("TagId");
|
||||
@@ -266,7 +275,11 @@ namespace Watcher.Migrations
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.Container", b =>
|
||||
{
|
||||
b.HasOne("Watcher.Models.Image", "Image")
|
||||
b.HasOne("Watcher.Models.Server", "HostServer")
|
||||
.WithMany()
|
||||
.HasForeignKey("HostServerId");
|
||||
|
||||
b.HasOne("Watcher.Models.Image", null)
|
||||
.WithMany("Containers")
|
||||
.HasForeignKey("ImageId");
|
||||
|
||||
@@ -274,7 +287,7 @@ namespace Watcher.Migrations
|
||||
.WithMany("Containers")
|
||||
.HasForeignKey("TagId");
|
||||
|
||||
b.Navigation("Image");
|
||||
b.Navigation("HostServer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Watcher.Models.LogEvent", b =>
|
||||
|
@@ -3,8 +3,10 @@ using Watcher.Models;
|
||||
namespace Watcher.ViewModels
|
||||
{
|
||||
public class ContainerOverviewViewModel
|
||||
{
|
||||
public List<Container> Containers { get; set; } = new();
|
||||
}
|
||||
{
|
||||
public List<Container> Containers { get; set; } = new();
|
||||
|
||||
public List<Server> Servers { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4,13 +4,30 @@
|
||||
}
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
@foreach (var container in Model.Containers)
|
||||
@foreach (var server in Model.Servers)
|
||||
{
|
||||
<div class="bg-white shadow-md rounded-xl p-5 border border-gray-200 hover:shadow-lg transition duration-200">
|
||||
<h2 class="text-xl font-semibold mb-1">@container.Name</h2>
|
||||
<p class="text-sm text-gray-600 mb-2"><strong>Image:</strong> @container.Image</p>
|
||||
<h2 class="text-xl font-semibold mb-1">@server.Name</h2>
|
||||
</div>
|
||||
|
||||
<div class="bg-white">
|
||||
@if (Model.Containers.Count > 0)
|
||||
{
|
||||
<table>
|
||||
@foreach (var container in Model.Containers)
|
||||
{
|
||||
<tr>test</tr>
|
||||
if (container.HostServer.Equals(server.Name))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
</table>
|
||||
} else
|
||||
{
|
||||
<p> keine Container gefunden </p>
|
||||
}
|
||||
|
||||
<p class="text-sm text-gray-600"><strong>Status:</strong> @(container.IsRunning ? "online" : "offline")</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
@@ -42,12 +42,15 @@
|
||||
<i class="bi bi-bar-chart-fill me-1"></i> Metrics
|
||||
</a>
|
||||
|
||||
<a asp-asp-controller="Container" asp-action="Overview" asp-route-id="@s.Id" class="btn btn-outline-primary">
|
||||
<i class="bi bi-box-fill me-1"></i> Container
|
||||
</a>
|
||||
|
||||
<form asp-action="Delete" asp-route-id="@s.Id" method="post" onsubmit="return confirm('Diesen Server wirklich löschen?');" class="m-0">
|
||||
<button type="submit" class="btn btn-outline-danger">
|
||||
<i class="bi bi-trash me-1"></i> Löschen
|
||||
</button>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user