From 9df2c18dad11a88bc4223febb55bf33e93eb1d96 Mon Sep 17 00:00:00 2001 From: daniel-hbn Date: Sat, 21 Jun 2025 14:50:38 +0200 Subject: [PATCH 1/2] Issue#32 Database Update + Systemanpassung an neue Parameter --- Watcher/Controllers/AuthController.cs | 20 +- Watcher/Controllers/HomeController.cs | 2 +- ...50621124832_DB-Update Issue#32.Designer.cs | 316 ++++++++++++++++++ .../20250621124832_DB-Update Issue#32.cs | 251 ++++++++++++++ .../Migrations/AppDbContextModelSnapshot.cs | 74 ++-- Watcher/Models/Metric.cs | 42 ++- Watcher/Models/Server.cs | 25 +- Watcher/Models/User.cs | 7 +- Watcher/Program.cs | 12 +- Watcher/persistence/watcher.db-shm | Bin 0 -> 32768 bytes Watcher/persistence/watcher.db-wal | Bin 0 -> 70072 bytes 11 files changed, 681 insertions(+), 68 deletions(-) create mode 100644 Watcher/Migrations/20250621124832_DB-Update Issue#32.Designer.cs create mode 100644 Watcher/Migrations/20250621124832_DB-Update Issue#32.cs create mode 100644 Watcher/persistence/watcher.db-shm create mode 100644 Watcher/persistence/watcher.db-wal diff --git a/Watcher/Controllers/AuthController.cs b/Watcher/Controllers/AuthController.cs index bd15c18..bf53f48 100644 --- a/Watcher/Controllers/AuthController.cs +++ b/Watcher/Controllers/AuthController.cs @@ -36,7 +36,7 @@ public class AuthController : Controller if (!ModelState.IsValid) return View(model); - var user = await _context.Users.FirstOrDefaultAsync(u => u.PreferredUsername == model.Username); + var user = await _context.Users.FirstOrDefaultAsync(u => u.Username == model.Username); if (user == null || !BCrypt.Net.BCrypt.Verify(model.Password, user.Password)) { ModelState.AddModelError("", "Benutzername oder Passwort ist falsch."); @@ -45,7 +45,7 @@ public class AuthController : Controller var claims = new List { - new Claim(ClaimTypes.Name, user.PreferredUsername), + new Claim(ClaimTypes.Name, user.Username), new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), }; @@ -100,12 +100,12 @@ public class AuthController : Controller public IActionResult Edit() { var username = User.Identity?.Name; - var user = _context.Users.FirstOrDefault(u => u.PreferredUsername == username); + var user = _context.Users.FirstOrDefault(u => u.Username == username); if (user == null) return NotFound(); var model = new EditUserViewModel { - Username = user.PreferredUsername + Username = user.Username }; return View(model); } @@ -119,10 +119,10 @@ public class AuthController : Controller if (!ModelState.IsValid) return View(model); var username = User.Identity?.Name; - var user = _context.Users.FirstOrDefault(u => u.PreferredUsername == username); + var user = _context.Users.FirstOrDefault(u => u.Username == username); if (user == null) return NotFound(); - user.PreferredUsername = model.Username; + user.Username = model.Username; if (!string.IsNullOrWhiteSpace(model.NewPassword)) { @@ -144,7 +144,7 @@ public class AuthController : Controller var username = User.Identity?.Name; var claims = User.Claims.Select(c => new { c.Type, c.Value }).ToList(); - var user = _context.Users.FirstOrDefault(u => u.PreferredUsername == username); + var user = _context.Users.FirstOrDefault(u => u.Username == username); if (user == null) return NotFound(); var DbProvider = _context.Database.ProviderName; @@ -166,17 +166,17 @@ public class AuthController : Controller if (!ModelState.IsValid) return View(model); var username = User.Identity?.Name; - var user = _context.Users.FirstOrDefault(u => u.PreferredUsername == username); + var user = _context.Users.FirstOrDefault(u => u.Username == username); if (user == null) return NotFound(); var databaseProvider = _context.Database.ProviderName; - user.PreferredUsername = model.Username; + user.Username = model.Username; // Passwort ändern if (!string.IsNullOrWhiteSpace(model.NewPassword)) { - user.PreferredUsername = BCrypt.Net.BCrypt.HashPassword(model.NewPassword); + user.Username = BCrypt.Net.BCrypt.HashPassword(model.NewPassword); } _context.SaveChanges(); diff --git a/Watcher/Controllers/HomeController.cs b/Watcher/Controllers/HomeController.cs index 2010961..aa64f6a 100644 --- a/Watcher/Controllers/HomeController.cs +++ b/Watcher/Controllers/HomeController.cs @@ -24,7 +24,7 @@ namespace Watcher.Controllers var user = await _context.Users - .Where(u => u.PreferredUsername == preferredUserName) + .Where(u => u.Username == preferredUserName) .FirstOrDefaultAsync(); var viewModel = new DashboardViewModel diff --git a/Watcher/Migrations/20250621124832_DB-Update Issue#32.Designer.cs b/Watcher/Migrations/20250621124832_DB-Update Issue#32.Designer.cs new file mode 100644 index 0000000..e8cad36 --- /dev/null +++ b/Watcher/Migrations/20250621124832_DB-Update Issue#32.Designer.cs @@ -0,0 +1,316 @@ +// +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("20250621124832_DB-Update Issue#32")] + partial class DBUpdateIssue32 + { + /// + 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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Hostname") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("IsRunning") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TagId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("TagId"); + + b.ToTable("Containers"); + }); + + modelBuilder.Entity("Watcher.Models.Image", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Tag") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("Watcher.Models.LogEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ContainerId") + .HasColumnType("INTEGER"); + + b.Property("Level") + .HasColumnType("TEXT"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("ServerId"); + + b.ToTable("LogEvents"); + }); + + modelBuilder.Entity("Watcher.Models.Metric", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CPU_Load") + .HasColumnType("REAL"); + + b.Property("CPU_Temp") + .HasColumnType("REAL"); + + b.Property("DISK_Size") + .HasColumnType("REAL"); + + b.Property("DISK_Temp") + .HasColumnType("REAL"); + + b.Property("DISK_Usage") + .HasColumnType("REAL"); + + b.Property("GPU_Load") + .HasColumnType("REAL"); + + b.Property("GPU_Temp") + .HasColumnType("REAL"); + + b.Property("GPU_Vram_Size") + .HasColumnType("REAL"); + + b.Property("GPU_Vram_Usage") + .HasColumnType("REAL"); + + b.Property("NET_In") + .HasColumnType("REAL"); + + b.Property("NET_Out") + .HasColumnType("REAL"); + + b.Property("RAM_Load") + .HasColumnType("REAL"); + + b.Property("RAM_Size") + .HasColumnType("REAL"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Metrics"); + }); + + modelBuilder.Entity("Watcher.Models.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CpuCores") + .HasColumnType("INTEGER"); + + b.Property("CpuType") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("GpuType") + .HasColumnType("TEXT"); + + b.Property("IPAddress") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsOnline") + .HasColumnType("INTEGER"); + + b.Property("LastSeen") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RamSize") + .HasColumnType("REAL"); + + b.Property("TagId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("TagId"); + + b.ToTable("Servers"); + }); + + modelBuilder.Entity("Watcher.Models.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Tags"); + }); + + modelBuilder.Entity("Watcher.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("IdentityProvider") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LastLogin") + .HasColumnType("TEXT"); + + b.Property("OIDC_Id") + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Watcher.Models.Container", b => + { + b.HasOne("Watcher.Models.Image", "Image") + .WithMany("Containers") + .HasForeignKey("ImageId"); + + b.HasOne("Watcher.Models.Tag", null) + .WithMany("Containers") + .HasForeignKey("TagId"); + + b.Navigation("Image"); + }); + + 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 + } + } +} diff --git a/Watcher/Migrations/20250621124832_DB-Update Issue#32.cs b/Watcher/Migrations/20250621124832_DB-Update Issue#32.cs new file mode 100644 index 0000000..b7644a8 --- /dev/null +++ b/Watcher/Migrations/20250621124832_DB-Update Issue#32.cs @@ -0,0 +1,251 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Watcher.Migrations +{ + /// + public partial class DBUpdateIssue32 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Metrics_Containers_ContainerId", + table: "Metrics"); + + migrationBuilder.DropForeignKey( + name: "FK_Metrics_Servers_ServerId", + table: "Metrics"); + + migrationBuilder.DropIndex( + name: "IX_Metrics_ContainerId", + table: "Metrics"); + + migrationBuilder.DropIndex( + name: "IX_Metrics_ServerId", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "PocketId", + table: "Users"); + + migrationBuilder.DropColumn( + name: "ContainerId", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "Type", + table: "Metrics"); + + migrationBuilder.RenameColumn( + name: "PreferredUsername", + table: "Users", + newName: "Username"); + + migrationBuilder.RenameColumn( + name: "Value", + table: "Metrics", + newName: "RAM_Size"); + + migrationBuilder.AddColumn( + name: "OIDC_Id", + table: "Users", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "CPU_Load", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "CPU_Temp", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "DISK_Size", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "DISK_Temp", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "DISK_Usage", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "GPU_Load", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "GPU_Temp", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "GPU_Vram_Size", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "GPU_Vram_Usage", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "NET_In", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "NET_Out", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "RAM_Load", + table: "Metrics", + type: "REAL", + nullable: false, + defaultValue: 0.0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "OIDC_Id", + table: "Users"); + + migrationBuilder.DropColumn( + name: "CPU_Load", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "CPU_Temp", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "DISK_Size", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "DISK_Temp", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "DISK_Usage", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "GPU_Load", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "GPU_Temp", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "GPU_Vram_Size", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "GPU_Vram_Usage", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "NET_In", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "NET_Out", + table: "Metrics"); + + migrationBuilder.DropColumn( + name: "RAM_Load", + table: "Metrics"); + + migrationBuilder.RenameColumn( + name: "Username", + table: "Users", + newName: "PreferredUsername"); + + migrationBuilder.RenameColumn( + name: "RAM_Size", + table: "Metrics", + newName: "Value"); + + migrationBuilder.AddColumn( + name: "PocketId", + table: "Users", + type: "TEXT", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "ContainerId", + table: "Metrics", + type: "INTEGER", + nullable: true); + + migrationBuilder.AddColumn( + name: "Type", + table: "Metrics", + type: "TEXT", + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Metrics_ContainerId", + table: "Metrics", + column: "ContainerId"); + + migrationBuilder.CreateIndex( + name: "IX_Metrics_ServerId", + table: "Metrics", + column: "ServerId"); + + migrationBuilder.AddForeignKey( + name: "FK_Metrics_Containers_ContainerId", + table: "Metrics", + column: "ContainerId", + principalTable: "Containers", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Metrics_Servers_ServerId", + table: "Metrics", + column: "ServerId", + principalTable: "Servers", + principalColumn: "Id"); + } + } +} diff --git a/Watcher/Migrations/AppDbContextModelSnapshot.cs b/Watcher/Migrations/AppDbContextModelSnapshot.cs index 1231da3..1f76d39 100644 --- a/Watcher/Migrations/AppDbContextModelSnapshot.cs +++ b/Watcher/Migrations/AppDbContextModelSnapshot.cs @@ -113,8 +113,44 @@ namespace Watcher.Migrations .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); - b.Property("ContainerId") - .HasColumnType("INTEGER"); + b.Property("CPU_Load") + .HasColumnType("REAL"); + + b.Property("CPU_Temp") + .HasColumnType("REAL"); + + b.Property("DISK_Size") + .HasColumnType("REAL"); + + b.Property("DISK_Temp") + .HasColumnType("REAL"); + + b.Property("DISK_Usage") + .HasColumnType("REAL"); + + b.Property("GPU_Load") + .HasColumnType("REAL"); + + b.Property("GPU_Temp") + .HasColumnType("REAL"); + + b.Property("GPU_Vram_Size") + .HasColumnType("REAL"); + + b.Property("GPU_Vram_Usage") + .HasColumnType("REAL"); + + b.Property("NET_In") + .HasColumnType("REAL"); + + b.Property("NET_Out") + .HasColumnType("REAL"); + + b.Property("RAM_Load") + .HasColumnType("REAL"); + + b.Property("RAM_Size") + .HasColumnType("REAL"); b.Property("ServerId") .HasColumnType("INTEGER"); @@ -122,18 +158,8 @@ namespace Watcher.Migrations b.Property("Timestamp") .HasColumnType("TEXT"); - b.Property("Type") - .HasColumnType("TEXT"); - - b.Property("Value") - .HasColumnType("REAL"); - b.HasKey("Id"); - b.HasIndex("ContainerId"); - - b.HasIndex("ServerId"); - b.ToTable("Metrics"); }); @@ -219,15 +245,14 @@ namespace Watcher.Migrations b.Property("LastLogin") .HasColumnType("TEXT"); + b.Property("OIDC_Id") + .HasColumnType("TEXT"); + b.Property("Password") .IsRequired() .HasColumnType("TEXT"); - b.Property("PocketId") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("PreferredUsername") + b.Property("Username") .IsRequired() .HasColumnType("TEXT"); @@ -264,21 +289,6 @@ namespace Watcher.Migrations b.Navigation("Server"); }); - modelBuilder.Entity("Watcher.Models.Metric", 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) diff --git a/Watcher/Models/Metric.cs b/Watcher/Models/Metric.cs index e069057..36913f8 100644 --- a/Watcher/Models/Metric.cs +++ b/Watcher/Models/Metric.cs @@ -2,15 +2,47 @@ namespace Watcher.Models; public class Metric { + // Metric Metadata public int Id { get; set; } public DateTime Timestamp { get; set; } - public string? Type { get; set; } // z.B. "CPU", "RAM", "Disk", "Network" - public double Value { get; set; } + // Zuordnung zu einem Server -- Foreign Key public int? ServerId { get; set; } - public Server? Server { get; set; } - public int? ContainerId { get; set; } - public Container? Container { get; set; } + + // CPU-Daten + public double CPU_Load { get; set; } = 0.0; // % + + public double CPU_Temp { get; set; } = 0.0; // deg C + + + // GPU-Daten + public double GPU_Load { get; set; } = 0.0; // % + + public double GPU_Temp { get; set; } = 0.0; // deg C + + public double GPU_Vram_Size { get; set; } // GB + + public double GPU_Vram_Usage { get; set; } // % + + + // RAM-Daten + public double RAM_Size { get; set; } = 0.0; // GB + + public double RAM_Load { get; set; } = 0.0; // % + + + // HDD-Daten + public double DISK_Size { get; set; } = 0.0; // GB + + public double DISK_Usage { get; set; } = 0.0; // % + + public double DISK_Temp { get; set; } = 0.0; // deg C + + + // Network-Daten + public double NET_In { get; set; } = 0.0; // Bit + + public double NET_Out { get; set; } = 0.0; // Bit } diff --git a/Watcher/Models/Server.cs b/Watcher/Models/Server.cs index 14121a0..b65fda6 100644 --- a/Watcher/Models/Server.cs +++ b/Watcher/Models/Server.cs @@ -5,32 +5,33 @@ namespace Watcher.Models; public class Server { + // System Infos [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } - public string Name { get; set; } = string.Empty; + [Required] + public required string Name { get; set; } - public string IPAddress { get; set; } = string.Empty; + public required string IPAddress { get; set; } - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + public required string Type { get; set; } - // z.B. "VPS", "standalone", "VM", etc. - public string Type { get; set; } = "VPS"; + public string? Description { get; set; } = String.Empty; - public Boolean IsOnline { get; set; } = false; - - public DateTime LastSeen { get; set; } - - public string? Description { get; set; } // Hardware Infos public string? CpuType { get; set; } = string.Empty; - public int CpuCores { get; set; } + public int CpuCores { get; set; } = 0; public string? GpuType { get; set; } = string.Empty; - public double RamSize { get; set; } + public double RamSize { get; set; } = 0; + // Database + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + + public Boolean IsOnline { get; set; } = false; + public DateTime LastSeen { get; set; } } diff --git a/Watcher/Models/User.cs b/Watcher/Models/User.cs index 10d0f0c..13d366a 100644 --- a/Watcher/Models/User.cs +++ b/Watcher/Models/User.cs @@ -1,12 +1,15 @@ using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; namespace Watcher.Models; public class User { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } // PK - public string PocketId { get; set; } = null!; - public string PreferredUsername { get; set; } = null!; + public string? OIDC_Id { get; set; } = null!; + public string Username { get; set; } = null!; public string? Email { get; set; } public DateTime LastLogin { get; set; } diff --git a/Watcher/Program.cs b/Watcher/Program.cs index 4765b87..baba787 100644 --- a/Watcher/Program.cs +++ b/Watcher/Program.cs @@ -95,14 +95,14 @@ builder.Services.AddAuthentication() if (string.IsNullOrEmpty(pocketId)) return; - var user = await db.Users.FirstOrDefaultAsync(u => u.PocketId == pocketId); + var user = await db.Users.FirstOrDefaultAsync(u => u.OIDC_Id == pocketId); if (user == null) { user = new User { - PocketId = pocketId, - PreferredUsername = preferredUsername ?? "", + OIDC_Id = pocketId, + Username = preferredUsername ?? "", Email = email, LastLogin = DateTime.UtcNow, IdentityProvider = "oidc", @@ -113,7 +113,7 @@ builder.Services.AddAuthentication() else { user.LastLogin = DateTime.UtcNow; - user.PreferredUsername = preferredUsername ?? user.PreferredUsername; + user.Username = preferredUsername ?? user.Username; user.Email = email ?? user.Email; db.Users.Update(user); } @@ -151,8 +151,8 @@ using (var scope = app.Services.CreateScope()) var defaultUser = new User { - PocketId = string.Empty, - PreferredUsername = "admin", + OIDC_Id = string.Empty, + Username = "admin", Email = string.Empty, LastLogin = DateTime.UtcNow, IdentityProvider = "local", diff --git a/Watcher/persistence/watcher.db-shm b/Watcher/persistence/watcher.db-shm new file mode 100644 index 0000000000000000000000000000000000000000..e67690b75729c115d6b74e02c23362a8a1caa1dd GIT binary patch literal 32768 zcmeI*JxT*X6bJAzAI7g}#3qPDuoUbCo1DYm19%ZnkVfzTT6qc^dm9_^5Tb9EAY!#b z5N7B1;Ln8J$7JSrfVb1vvy^KPSxafMAL~hEetLQP{`5A!e|~tpSX>{>Kdx@hXD@ft zKlaB~P33(*f7J5v_cDuL@&9QUS&wW+b|T}*QRMf#!{zhiSbLFvL=hlBfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72$Uw!YvxRpc53G(unK|6DmJkPfg%O+L?T6i0D*1@8(Fmx7&bGd+jQzFMPRR#gE}Vx0t5&U_;-Q) qO$|k$PJvOK*LG_H1PBlyK!5-N0t5&UAV7cs0RjXF5FkLHN`Wsn`6&tj literal 0 HcmV?d00001 diff --git a/Watcher/persistence/watcher.db-wal b/Watcher/persistence/watcher.db-wal new file mode 100644 index 0000000000000000000000000000000000000000..449efe8ec39fa895b16b794aac638fde6a1c5852 GIT binary patch literal 70072 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 Date: Sat, 21 Jun 2025 14:52:39 +0200 Subject: [PATCH 2/2] =?UTF-8?q?Issue#32=20Database=20Update=20IsVerified?= =?UTF-8?q?=20in=20Server=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...te Issue#32 IsVerified-Servers.Designer.cs | 319 ++++++++++++++++++ ...7_DB-Update Issue#32 IsVerified-Servers.cs | 29 ++ .../Migrations/AppDbContextModelSnapshot.cs | 3 + Watcher/Models/Server.cs | 4 +- Watcher/persistence/watcher.db-shm | Bin 32768 -> 32768 bytes Watcher/persistence/watcher.db-wal | Bin 70072 -> 82432 bytes 6 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.Designer.cs create mode 100644 Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.cs diff --git a/Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.Designer.cs b/Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.Designer.cs new file mode 100644 index 0000000..feb5c2e --- /dev/null +++ b/Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.Designer.cs @@ -0,0 +1,319 @@ +// +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("20250621125157_DB-Update Issue#32 IsVerified-Servers")] + partial class DBUpdateIssue32IsVerifiedServers + { + /// + 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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Hostname") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("IsRunning") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TagId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("TagId"); + + b.ToTable("Containers"); + }); + + modelBuilder.Entity("Watcher.Models.Image", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Tag") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("Watcher.Models.LogEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ContainerId") + .HasColumnType("INTEGER"); + + b.Property("Level") + .HasColumnType("TEXT"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("ServerId"); + + b.ToTable("LogEvents"); + }); + + modelBuilder.Entity("Watcher.Models.Metric", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CPU_Load") + .HasColumnType("REAL"); + + b.Property("CPU_Temp") + .HasColumnType("REAL"); + + b.Property("DISK_Size") + .HasColumnType("REAL"); + + b.Property("DISK_Temp") + .HasColumnType("REAL"); + + b.Property("DISK_Usage") + .HasColumnType("REAL"); + + b.Property("GPU_Load") + .HasColumnType("REAL"); + + b.Property("GPU_Temp") + .HasColumnType("REAL"); + + b.Property("GPU_Vram_Size") + .HasColumnType("REAL"); + + b.Property("GPU_Vram_Usage") + .HasColumnType("REAL"); + + b.Property("NET_In") + .HasColumnType("REAL"); + + b.Property("NET_Out") + .HasColumnType("REAL"); + + b.Property("RAM_Load") + .HasColumnType("REAL"); + + b.Property("RAM_Size") + .HasColumnType("REAL"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Metrics"); + }); + + modelBuilder.Entity("Watcher.Models.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CpuCores") + .HasColumnType("INTEGER"); + + b.Property("CpuType") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("GpuType") + .HasColumnType("TEXT"); + + b.Property("IPAddress") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsOnline") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastSeen") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RamSize") + .HasColumnType("REAL"); + + b.Property("TagId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("TagId"); + + b.ToTable("Servers"); + }); + + modelBuilder.Entity("Watcher.Models.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Tags"); + }); + + modelBuilder.Entity("Watcher.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("IdentityProvider") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LastLogin") + .HasColumnType("TEXT"); + + b.Property("OIDC_Id") + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Watcher.Models.Container", b => + { + b.HasOne("Watcher.Models.Image", "Image") + .WithMany("Containers") + .HasForeignKey("ImageId"); + + b.HasOne("Watcher.Models.Tag", null) + .WithMany("Containers") + .HasForeignKey("TagId"); + + b.Navigation("Image"); + }); + + 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 + } + } +} diff --git a/Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.cs b/Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.cs new file mode 100644 index 0000000..974f389 --- /dev/null +++ b/Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Watcher.Migrations +{ + /// + public partial class DBUpdateIssue32IsVerifiedServers : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IsVerified", + table: "Servers", + type: "INTEGER", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsVerified", + table: "Servers"); + } + } +} diff --git a/Watcher/Migrations/AppDbContextModelSnapshot.cs b/Watcher/Migrations/AppDbContextModelSnapshot.cs index 1f76d39..11d908f 100644 --- a/Watcher/Migrations/AppDbContextModelSnapshot.cs +++ b/Watcher/Migrations/AppDbContextModelSnapshot.cs @@ -191,6 +191,9 @@ namespace Watcher.Migrations b.Property("IsOnline") .HasColumnType("INTEGER"); + b.Property("IsVerified") + .HasColumnType("INTEGER"); + b.Property("LastSeen") .HasColumnType("TEXT"); diff --git a/Watcher/Models/Server.cs b/Watcher/Models/Server.cs index b65fda6..83466a8 100644 --- a/Watcher/Models/Server.cs +++ b/Watcher/Models/Server.cs @@ -29,9 +29,11 @@ public class Server // Database public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - + public Boolean IsOnline { get; set; } = false; public DateTime LastSeen { get; set; } + + public Boolean IsVerified { get; set; } = false; } diff --git a/Watcher/persistence/watcher.db-shm b/Watcher/persistence/watcher.db-shm index e67690b75729c115d6b74e02c23362a8a1caa1dd..f7da6f31f912c850023b628b3a70db618237dde2 100644 GIT binary patch delta 143 zcmZo@U}|V!N|1P@%K!qbK+MR%ARq#ym4G-Td}`0iaJHozE^XXyJ*QCE<>9a2iaSqF xAyxgvgd9f3jRy^#SeY0&8H6@o{K>>Dz#zQw;%_EqK?aeH7tgb7KI3a*1OPk0ET8}Y delta 138 zcmZo@U}|V!N|1P@%K!o_K+MR%ARq{&m4MhmD{A4(v(I@qT-vzZdQPFR!{5|C3%R>X sNL4>EA!p+aHK&Omc$k?OI5$50&BQ3M@!?-4M!}5_FS2Yt<7;9B0A8Xjz5oCK diff --git a/Watcher/persistence/watcher.db-wal b/Watcher/persistence/watcher.db-wal index 449efe8ec39fa895b16b794aac638fde6a1c5852..cd00959c0901bf5009275482628f7da2030e5be7 100644 GIT binary patch delta 376 zcmdn7n5ChGwP6e64nYY91_nkTX4r6P<96#gg~HVj@*^f%ad%G+5RevR0ZJ$VF((iU z0kP}k8UbT%76!evSG+(jKcfo+zXso3zHZ*Xj4nL<+$o&K95*W-0j7$y8 zj0_EpObt!V<6WF|Lkm(8OHvg)i;GKBm5q&n45+m!y1}VMWvNBQ7J3GHW>bGMZkOtr z8XmHgEqo;x*alMu{=57;`KR#b@tbZ8ROYv}U@m1O#{yPWW`D-1{}>ggdkZq=0suq9 BXej^y delta 11 ScmZo@VcoHqrC|%>4nY7M0R(3N