diff --git a/.gitignore b/.gitignore index cc031e3..ff87601 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ +# Per-Use special Files and Directories +/persistance/*.db +/logs +*.env +/wwwroot/downloads/sqlite/*.sql + +/persistence/*.db-shm +/persistence/*.db-wal + # Build-Ordner bin/ obj/ diff --git a/Watcher/.env.example b/Watcher/.env.example new file mode 100644 index 0000000..032d787 --- /dev/null +++ b/Watcher/.env.example @@ -0,0 +1,8 @@ + +# OIDC Einstellungen +AUTHENTICATION__USELOCAL=true +AUTHENTICATION__POCKETID__ENABLED=false +AUTHENTICATION__POCKETID__AUTHORITY=https://id.domain.app +AUTHENTICATION__POCKETID__CLIENTID= +AUTHENTICATION__POCKETID__CLIENTSECRET= +AUTHENTICATION__POCKETID__CALLBACKPATH=/signin-oidc diff --git a/Watcher/Controllers/AuthController.cs b/Watcher/Controllers/AuthController.cs index 971a3ff..861890b 100644 --- a/Watcher/Controllers/AuthController.cs +++ b/Watcher/Controllers/AuthController.cs @@ -1,21 +1,69 @@ +using System.Net.Mail; +using System.Security.Claims; +using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Watcher.Data; +using Watcher.ViewModels; namespace Watcher.Controllers; public class AuthController : Controller { - public IActionResult Login() + private readonly AppDbContext _context; + + public AuthController(AppDbContext context) { - return View(); + _context = context; } + [HttpGet] + public IActionResult Login(string? returnUrl = null) + { + var model = new LoginViewModel + { + ReturnUrl = returnUrl + }; + return View(model); + } + + + [HttpPost] + public async Task Login(LoginViewModel model) + { + if (!ModelState.IsValid) + return View(model); + + 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."); + return View(model); + } + + var claims = new List + { + new Claim(ClaimTypes.Name, user.Username), + new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), + }; + + var identity = new ClaimsIdentity(claims, "local"); + var principal = new ClaimsPrincipal(identity); + + await HttpContext.SignInAsync("Cookies", principal); + + return Redirect("Home/Index"); + } + + public IActionResult SignIn() { return Challenge(new AuthenticationProperties { - RedirectUri = "/" + RedirectUri = "/Home/Index" }, "oidc"); } @@ -23,19 +71,132 @@ public class AuthController : Controller [ValidateAntiForgeryToken] public async Task Logout() { - await HttpContext.SignOutAsync(); - return RedirectToAction("Index", "Home"); + var props = new AuthenticationProperties + { + RedirectUri = Url.Action("Login", "Auth") + }; + + await HttpContext.SignOutAsync("Cookies"); + await HttpContext.SignOutAsync("oidc", props); + + return Redirect("/"); // nur als Fallback } + [Authorize] public IActionResult Info() { - var name = User.Identity?.Name; + var username = User.Identity?.Name; + Console.WriteLine("gefundener User: " + username); var claims = User.Claims.Select(c => new { c.Type, c.Value }).ToList(); - ViewBag.Name = name; + var user = _context.Users.FirstOrDefault(u => u.Username == username); + if (user == null) return NotFound(); + + var DbProvider = _context.Database.ProviderName; + var mail = user.Email; + var Id = user.Id; + + ViewBag.Name = username; ViewBag.Claims = claims; + ViewBag.Mail = mail; + ViewBag.Id = Id; return View(); } + + // Edit-Form anzeigen + [Authorize] + [HttpGet] + public IActionResult Edit() + { + var username = User.Identity?.Name; + var user = _context.Users.FirstOrDefault(u => u.Username == username); + if (user == null) return NotFound(); + + var model = new EditUserViewModel + { + Username = user.Username + }; + return View(model); + } + + // Edit speichern + [Authorize] + [HttpPost] + [ValidateAntiForgeryToken] + public IActionResult Edit(EditUserViewModel model) + { + if (!ModelState.IsValid) return View(model); + + var username = User.Identity?.Name; + var user = _context.Users.FirstOrDefault(u => u.Username == username); + if (user == null) return NotFound(); + + user.Username = model.Username; + + if (!string.IsNullOrWhiteSpace(model.NewPassword)) + { + user.Password = BCrypt.Net.BCrypt.HashPassword(model.NewPassword); + } + + _context.SaveChanges(); + + // Eventuell hier das Auth-Cookie erneuern, wenn Username sich ändert + + return RedirectToAction("Index", "Home"); + } + + // Edit-Form anzeigen + [Authorize] + [HttpGet] + public IActionResult UserSettings() + { + var username = User.Identity?.Name; + Console.WriteLine("gefundener User: " + username); + var claims = User.Claims.Select(c => new { c.Type, c.Value }).ToList(); + + var user = _context.Users.FirstOrDefault(u => u.Username == username); + if (user == null) return NotFound(); + + var DbProvider = _context.Database.ProviderName; + var mail = user.Email; + + ViewBag.Name = username; + ViewBag.mail = mail; + ViewBag.Claims = claims; + ViewBag.IdentityProvider = user.IdentityProvider; + ViewBag.DbProvider = DbProvider; + + return View(); + } + + // Edit speichern + [Authorize] + [HttpPost] + [ValidateAntiForgeryToken] + public IActionResult UserSettings(EditUserViewModel model) + { + if (!ModelState.IsValid) return View(model); + + var username = User.Identity?.Name; + var user = _context.Users.FirstOrDefault(u => u.Username == username); + if (user == null) return NotFound(); + + var databaseProvider = _context.Database.ProviderName; + + user.Username = model.Username; + + // Passwort ändern + if (!string.IsNullOrWhiteSpace(model.NewPassword)) + { + user.Username = BCrypt.Net.BCrypt.HashPassword(model.NewPassword); + } + + _context.SaveChanges(); + + // Eventuell hier das Auth-Cookie erneuern, wenn Username sich ändert + + return RedirectToAction("Index", "Home"); + } } diff --git a/Watcher/Controllers/ContainerController.cs b/Watcher/Controllers/ContainerController.cs index 624a1a8..e65c127 100644 --- a/Watcher/Controllers/ContainerController.cs +++ b/Watcher/Controllers/ContainerController.cs @@ -7,7 +7,7 @@ using Watcher.ViewModels; namespace Watcher.Controllers; - +[Authorize] public class ContainerController : Controller { private readonly AppDbContext _context; diff --git a/Watcher/Controllers/DatabaseController.cs b/Watcher/Controllers/DatabaseController.cs new file mode 100644 index 0000000..0bfcd27 --- /dev/null +++ b/Watcher/Controllers/DatabaseController.cs @@ -0,0 +1,185 @@ +using System.Runtime.InteropServices; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; +using System.IO; +using System.Diagnostics; + +namespace Watcher.Controllers +{ + [Authorize] + public class DatabaseController : Controller + { + private readonly string _dbPath = Path.Combine(Directory.GetCurrentDirectory(), "persistence", "watcher.db"); + private readonly string _backupFolder = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "downloads", "sqlite"); + + + public class DumpFileInfo + { + public string? FileName { get; set; } + public long SizeKb { get; set; } + public DateTime Created { get; set; } + } + + + public DatabaseController(IWebHostEnvironment env) + { + _backupFolder = Path.Combine(env.WebRootPath, "downloads", "sqlite"); + + if (!Directory.Exists(_backupFolder)) + Directory.CreateDirectory(_backupFolder); + } + + [HttpPost("/maintenance/sqlite-dump")] + public IActionResult CreateSqlDump() + { + try + { + // Zielordner sicherstellen + if (!Directory.Exists(_backupFolder)) + Directory.CreateDirectory(_backupFolder); + + // Ziel-Dateiname z. B. mit Zeitstempel + var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss"); + var dumpFileName = $"watcher_dump_{timestamp}.sql"; + var dumpFilePath = Path.Combine(_backupFolder, dumpFileName); + + using var connection = new SqliteConnection($"Data Source={_dbPath}"); + connection.Open(); + + using var command = connection.CreateCommand(); + command.CommandText = "SELECT sql FROM sqlite_master WHERE type='table' AND sql IS NOT NULL;"; + using var writer = new StreamWriter(dumpFilePath); + + // Write schema + using (var schemaCmd = connection.CreateCommand()) + { + schemaCmd.CommandText = "SELECT sql FROM sqlite_master WHERE type='table'"; + using var reader = schemaCmd.ExecuteReader(); + while (reader.Read()) + { + writer.WriteLine(reader.GetString(0) + ";"); + } + } + + // Write content + using (var tableCmd = connection.CreateCommand()) + { + tableCmd.CommandText = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'"; + using var tableReader = tableCmd.ExecuteReader(); + while (tableReader.Read()) + { + var tableName = tableReader.GetString(0); + using var dataCmd = connection.CreateCommand(); + dataCmd.CommandText = $"SELECT * FROM {tableName}"; + using var dataReader = dataCmd.ExecuteReader(); + + while (dataReader.Read()) + { + var columns = new string[dataReader.FieldCount]; + var values = new string[dataReader.FieldCount]; + + for (int i = 0; i < dataReader.FieldCount; i++) + { + columns[i] = dataReader.GetName(i); + var val = dataReader.GetValue(i); + values[i] = val == null || val == DBNull.Value + ? "NULL" + : $"'{val.ToString().Replace("'", "''")}'"; + } + + writer.WriteLine($"INSERT INTO {tableName} ({string.Join(",", columns)}) VALUES ({string.Join(",", values)});"); + } + } + } + + writer.Flush(); + + //return Ok($"Dump erfolgreich erstellt: {dumpFileName}"); + + TempData["DumpMessage"] = "SQLite-Dump erfolgreich erstellt."; + return RedirectToAction("UserSettings", "Auth"); + } + catch (Exception ex) + { + //return StatusCode(500, $"Fehler beim Erstellen des Dumps: {ex.Message}"); + TempData["DumpError"] = $"Fehler beim Erstellen des Dumps: {ex.Message}"; + return RedirectToAction("UserSettings", "Auth"); + } + } + + public IActionResult ManageSqlDumps() + { + var files = Directory.GetFiles(_backupFolder, "*.sql") + .Select(f => new DumpFileInfo + { + FileName = Path.GetFileName(f), + SizeKb = new FileInfo(f).Length / 1024, + Created = System.IO.File.GetCreationTime(f) + }) + .OrderByDescending(f => f.Created) + .ToList(); + + return View(files); + } + + [HttpPost] + public IActionResult Delete(string fileName) + { + var filePath = Path.Combine(_backupFolder, fileName); + if (System.IO.File.Exists(filePath)) + { + System.IO.File.Delete(filePath); + TempData["Success"] = $"Backup {fileName} wurde gelöscht."; + } + + return RedirectToAction("ManageSqlDumps"); + } + + // 🔹 4. Dump wiederherstellen + [HttpPost] + public IActionResult Restore(string fileName) + { + var filePath = Path.Combine(_backupFolder, fileName); + if (!System.IO.File.Exists(filePath)) + { + TempData["Error"] = "Dump nicht gefunden."; + return RedirectToAction("ManageSqlDumps"); + } + + try + { + var dbPath = Path.Combine(Directory.GetCurrentDirectory(), "persistence", "watcher.db"); // anpassen + + // Leere Datenbank + System.IO.File.WriteAllText(dbPath, ""); + + var psi = new ProcessStartInfo + { + FileName = "sqlite3", + Arguments = $"\"{dbPath}\" \".read \\\"{filePath}\\\"\"", + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true, + }; + + using var proc = Process.Start(psi); + proc.WaitForExit(); + + TempData["Success"] = $"Backup {fileName} wurde wiederhergestellt."; + } + catch (Exception ex) + { + TempData["Error"] = $"Fehler beim Wiederherstellen: {ex.Message}"; + } + + return RedirectToAction("ManageSqlDumps"); + } + } + +} \ No newline at end of file diff --git a/Watcher/Controllers/DownloadController.cs b/Watcher/Controllers/DownloadController.cs new file mode 100644 index 0000000..d544652 --- /dev/null +++ b/Watcher/Controllers/DownloadController.cs @@ -0,0 +1,37 @@ +using System.Runtime.InteropServices; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace Watcher.Controllers; + +[Authorize] +public class DownloadController : Controller +{ + [HttpGet("Download/File/{type}/{filename}")] + public IActionResult FileDownload(string type, string filename) + { + // Nur erlaubte Endungen zulassen (Sicherheit!) + var allowedExtensions = new[] { ".exe", "", ".sql" }; + var extension = Path.GetExtension(filename).ToLowerInvariant(); + + if (!allowedExtensions.Contains(extension)) + return BadRequest("Dateityp nicht erlaubt"); + + var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "downloads", type, filename); + + if (!System.IO.File.Exists(path)) + return NotFound("Datei nicht gefunden"); + + // .exe MIME-Typ: application/octet-stream + var mimeType = "application/octet-stream"; + + var fileBytes = System.IO.File.ReadAllBytes(path); + + return File(fileBytes, mimeType, filename); + //return File(fileBytes, filename); + } +} diff --git a/Watcher/Controllers/HomeController.cs b/Watcher/Controllers/HomeController.cs index 83df394..aa64f6a 100644 --- a/Watcher/Controllers/HomeController.cs +++ b/Watcher/Controllers/HomeController.cs @@ -20,10 +20,11 @@ namespace Watcher.Controllers public async Task Index() { - var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + var preferredUserName = User.FindFirst("preferred_username")?.Value; + var user = await _context.Users - .Where(u => u.PocketId == userId) + .Where(u => u.Username == preferredUserName) .FirstOrDefaultAsync(); var viewModel = new DashboardViewModel @@ -37,5 +38,26 @@ namespace Watcher.Controllers return View(viewModel); } + + public IActionResult DashboardStats() + { + Console.WriteLine("Dashboard aktualisiert"); + var servers = _context.Servers.ToList(); + var containers = _context.Containers.ToList(); + + var now = DateTime.UtcNow; + + var model = new DashboardViewModel + { + ActiveServers = servers.Count(s => (now - s.LastSeen).TotalSeconds <= 120), + OfflineServers = servers.Count(s => (now - s.LastSeen).TotalSeconds > 120), + //RunningContainers = containers.Count(c => (now - c.LastSeen).TotalSeconds <= 120), + //FailedContainers = containers.Count(c => (now - c.LastSeen).TotalSeconds > 120), + LastLogin = DateTime.Now // Oder was auch immer hier richtig ist + }; + + return PartialView("_DashboardStats", model); + } + } } diff --git a/Watcher/Controllers/MonitoringController.cs b/Watcher/Controllers/MonitoringController.cs new file mode 100644 index 0000000..3f53df3 --- /dev/null +++ b/Watcher/Controllers/MonitoringController.cs @@ -0,0 +1,131 @@ +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.CodeAnalysis; +using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using Watcher.Data; +using Watcher.Models; +using Watcher.ViewModels; + +namespace Watcher.Controllers; + +public class RegistrationDto +{ + // Server Identity + [Required] + public int Id { get; set; } + + [Required] + public string? IpAddress { get; set; } + + // Hardware Info + [Required] + public string? CpuType { get; set; } + + [Required] + public int CpuCores { get; set; } + + [Required] + public string? GpuType { get; set; } + + [Required] + public double RamSize { get; set; } + +} + +public class MetricDto +{ + // Server Identity + [Required] + public int Id { get; set; } + + [Required] + public string? IpAddress { get; set; } + + // Metrics + // CPU Auslastung, CPU Temperatur + // GPU Auslastung, GPU Temperatur + // RAM Auslastung + // Disks? +} + +[ApiController] +[Route("[controller]")] +public class MonitoringController : Controller +{ + private readonly AppDbContext _context; + + public MonitoringController(AppDbContext context) + { + _context = context; + } + + [HttpPost("register")] + public async Task Register([FromBody] RegistrationDto dto) + { + // Gültigkeit des Payloads prüfen + if (!ModelState.IsValid) + { + var errors = ModelState.Values + .SelectMany(v => v.Errors) + .Select(e => e.ErrorMessage) + .ToList(); + + return BadRequest(new { error = "Ungültiger Payload", details = errors }); + } + + // Server in Datenbank finden + var server = await _context.Servers + .FirstOrDefaultAsync(s => s.IPAddress == dto.IpAddress); + + if (server != null) + { + // Serverdaten in Datenbank eintragen + server.CpuType = dto.CpuType; + server.CpuCores = dto.CpuCores; + server.GpuType = dto.GpuType; + server.RamSize = dto.RamSize; + + // Änderungen in Datenbank speichern + await _context.SaveChangesAsync(); + + // Success + return Ok(); + } + + return NotFound("No Matching Server found."); + + } + + [HttpPost("metric")] + public async Task Receive([FromBody] MetricDto dto) + { + // Gültigkeit des Payloads prüfen + if (!ModelState.IsValid) + { + var errors = ModelState.Values + .SelectMany(v => v.Errors) + .Select(e => e.ErrorMessage) + .ToList(); + + return BadRequest(new { error = "Ungültiger Payload", details = errors }); + } + + // Server in Datenbank finden + var server = await _context.Servers + .FirstOrDefaultAsync(s => s.IPAddress == dto.IpAddress); + + if (server != null) + { + // Serverdaten in Datenbank eintragen + + // Success + return Ok(); + } + + return NotFound("No Matching Server found."); + + } +} \ No newline at end of file diff --git a/Watcher/Controllers/ServerController.cs b/Watcher/Controllers/ServerController.cs index e4d89a3..b75678e 100644 --- a/Watcher/Controllers/ServerController.cs +++ b/Watcher/Controllers/ServerController.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -48,7 +49,7 @@ public class ServerController : Controller _context.Servers.Add(server); await _context.SaveChangesAsync(); - return RedirectToAction("Overview"); + return RedirectToAction(nameof(Overview)); } [HttpPost] @@ -103,4 +104,18 @@ public class ServerController : Controller return View(vm); } + public async Task ServerCardsPartial() + { + var servers = _context.Servers.ToList(); + + foreach (var server in servers) + { + server.IsOnline = (DateTime.UtcNow - server.LastSeen).TotalSeconds <= 120; + await _context.SaveChangesAsync(); + } + + return PartialView("_ServerCard", servers); // korrekt + } + + } diff --git a/Watcher/Data/AppDbContext.cs b/Watcher/Data/AppDbContext.cs index 8fbcc52..c88df1b 100644 --- a/Watcher/Data/AppDbContext.cs +++ b/Watcher/Data/AppDbContext.cs @@ -1,11 +1,18 @@ using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; using Watcher.Models; namespace Watcher.Data; public class AppDbContext : DbContext { - public AppDbContext(DbContextOptions options) : base(options) { } + private readonly IConfiguration _configuration; + + public AppDbContext(DbContextOptions options, IConfiguration configuration) + : base(options) + { + _configuration = configuration; + } public DbSet Containers { get; set; } @@ -21,6 +28,29 @@ public class AppDbContext : DbContext public DbSet Users { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!optionsBuilder.IsConfigured) + { + var provider = _configuration["Database:Provider"]; + + if (provider == "MySql") + { + var connStr = _configuration.GetConnectionString("MySql") + ?? _configuration["Database:ConnectionStrings:MySql"]; + optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr)); + } + else if (provider == "Sqlite") + { + var connStr = _configuration.GetConnectionString("Sqlite") + ?? _configuration["Database:ConnectionStrings:Sqlite"]; + optionsBuilder.UseSqlite(connStr); + } + else + { + throw new Exception("Unsupported database provider configured."); + } + } + } } - diff --git a/Watcher/Migrations/20250613213714_InitialCreate.Designer.cs b/Watcher/Migrations/20250613213714_InitialCreate.Designer.cs deleted file mode 100644 index 502ab4a..0000000 --- a/Watcher/Migrations/20250613213714_InitialCreate.Designer.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -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("20250613213714_InitialCreate")] - partial class InitialCreate - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 64); - - modelBuilder.Entity("Watcher.Models.Container", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime(6)"); - - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Name") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Type") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Containers"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Watcher/Migrations/20250613213714_InitialCreate.cs b/Watcher/Migrations/20250613213714_InitialCreate.cs deleted file mode 100644 index cc04d1f..0000000 --- a/Watcher/Migrations/20250613213714_InitialCreate.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Watcher.Migrations -{ - /// - public partial class InitialCreate : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterDatabase() - .Annotation("MySql:CharSet", "utf8mb4"); - - migrationBuilder.CreateTable( - name: "Containers", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), - Name = table.Column(type: "longtext", nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"), - Status = table.Column(type: "longtext", nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"), - CreatedAt = table.Column(type: "datetime(6)", nullable: false), - Hostname = table.Column(type: "longtext", nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"), - Type = table.Column(type: "longtext", nullable: false) - .Annotation("MySql:CharSet", "utf8mb4") - }, - constraints: table => - { - table.PrimaryKey("PK_Containers", x => x.Id); - }) - .Annotation("MySql:CharSet", "utf8mb4"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Containers"); - } - } -} diff --git a/Watcher/Migrations/20250613215617_ModelsAdded.Designer.cs b/Watcher/Migrations/20250613215617_ModelsAdded.Designer.cs deleted file mode 100644 index cd3d6b3..0000000 --- a/Watcher/Migrations/20250613215617_ModelsAdded.Designer.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -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("20250613215617_ModelsAdded")] - partial class ModelsAdded - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 64); - - modelBuilder.Entity("Watcher.Models.Container", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime(6)"); - - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Name") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Type") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Containers"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Watcher/Migrations/20250613215617_ModelsAdded.cs b/Watcher/Migrations/20250613215617_ModelsAdded.cs deleted file mode 100644 index 95e1fde..0000000 --- a/Watcher/Migrations/20250613215617_ModelsAdded.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Watcher.Migrations -{ - /// - public partial class ModelsAdded : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - - } - } -} diff --git a/Watcher/Migrations/20250614153746_ServerModelAdded.Designer.cs b/Watcher/Migrations/20250614153746_ServerModelAdded.Designer.cs deleted file mode 100644 index a43aa0d..0000000 --- a/Watcher/Migrations/20250614153746_ServerModelAdded.Designer.cs +++ /dev/null @@ -1,87 +0,0 @@ -// -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("20250614153746_ServerModelAdded")] - partial class ServerModelAdded - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 64); - - modelBuilder.Entity("Watcher.Models.Container", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime(6)"); - - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Name") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Type") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Containers"); - }); - - modelBuilder.Entity("Watcher.Models.Server", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime(6)"); - - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Name") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Type") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Servers"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Watcher/Migrations/20250614153746_ServerModelAdded.cs b/Watcher/Migrations/20250614153746_ServerModelAdded.cs deleted file mode 100644 index e63f373..0000000 --- a/Watcher/Migrations/20250614153746_ServerModelAdded.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Watcher.Migrations -{ - /// - public partial class ServerModelAdded : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Servers", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), - Name = table.Column(type: "longtext", nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"), - Status = table.Column(type: "longtext", nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"), - CreatedAt = table.Column(type: "datetime(6)", nullable: false), - Hostname = table.Column(type: "longtext", nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"), - Type = table.Column(type: "longtext", nullable: false) - .Annotation("MySql:CharSet", "utf8mb4") - }, - constraints: table => - { - table.PrimaryKey("PK_Servers", x => x.Id); - }) - .Annotation("MySql:CharSet", "utf8mb4"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Servers"); - } - } -} diff --git a/Watcher/Migrations/20250614154943_InitialModelsAdded.Designer.cs b/Watcher/Migrations/20250614154943_InitialModelsAdded.Designer.cs deleted file mode 100644 index 513374c..0000000 --- a/Watcher/Migrations/20250614154943_InitialModelsAdded.Designer.cs +++ /dev/null @@ -1,87 +0,0 @@ -// -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("20250614154943_InitialModelsAdded")] - partial class InitialModelsAdded - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 64); - - modelBuilder.Entity("Watcher.Models.Container", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime(6)"); - - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Name") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Type") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Containers"); - }); - - modelBuilder.Entity("Watcher.Models.Server", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime(6)"); - - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Name") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Type") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Servers"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Watcher/Migrations/20250614154943_InitialModelsAdded.cs b/Watcher/Migrations/20250614154943_InitialModelsAdded.cs deleted file mode 100644 index 0991d75..0000000 --- a/Watcher/Migrations/20250614154943_InitialModelsAdded.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Watcher.Migrations -{ - /// - public partial class InitialModelsAdded : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - - } - } -} diff --git a/Watcher/Migrations/20250614155203_InitialModelsAdded_1.Designer.cs b/Watcher/Migrations/20250614155203_InitialModelsAdded_1.Designer.cs deleted file mode 100644 index cfe2942..0000000 --- a/Watcher/Migrations/20250614155203_InitialModelsAdded_1.Designer.cs +++ /dev/null @@ -1,271 +0,0 @@ -// -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("20250614155203_InitialModelsAdded_1")] - partial class InitialModelsAdded_1 - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 64); - - modelBuilder.Entity("Watcher.Models.Container", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime(6)"); - - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("ImageId") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("TagId") - .HasColumnType("int"); - - b.Property("Type") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.HasIndex("ImageId"); - - b.HasIndex("TagId"); - - b.ToTable("Containers"); - }); - - modelBuilder.Entity("Watcher.Models.Image", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("Name") - .HasColumnType("longtext"); - - b.Property("Tag") - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Images"); - }); - - modelBuilder.Entity("Watcher.Models.LogEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("ContainerId") - .HasColumnType("int"); - - b.Property("Level") - .HasColumnType("longtext"); - - b.Property("Message") - .HasColumnType("longtext"); - - b.Property("ServerId") - .HasColumnType("int"); - - b.Property("Timestamp") - .HasColumnType("datetime(6)"); - - b.HasKey("Id"); - - b.HasIndex("ContainerId"); - - b.HasIndex("ServerId"); - - b.ToTable("LogEvents"); - }); - - modelBuilder.Entity("Watcher.Models.Metric", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("ContainerId") - .HasColumnType("int"); - - b.Property("ServerId") - .HasColumnType("int"); - - b.Property("Timestamp") - .HasColumnType("datetime(6)"); - - b.Property("Type") - .HasColumnType("longtext"); - - b.Property("Value") - .HasColumnType("double"); - - b.HasKey("Id"); - - b.HasIndex("ContainerId"); - - b.HasIndex("ServerId"); - - b.ToTable("Metrics"); - }); - - modelBuilder.Entity("Watcher.Models.Server", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime(6)"); - - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Name") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("TagId") - .HasColumnType("int"); - - b.Property("Type") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.HasIndex("TagId"); - - b.ToTable("Servers"); - }); - - modelBuilder.Entity("Watcher.Models.Tag", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("Name") - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Tags"); - }); - - modelBuilder.Entity("Watcher.Models.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("PocketId") - .HasColumnType("longtext"); - - b.Property("Role") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("Watcher.Models.Container", b => - { - b.HasOne("Watcher.Models.Image", null) - .WithMany("Containers") - .HasForeignKey("ImageId"); - - b.HasOne("Watcher.Models.Tag", null) - .WithMany("Containers") - .HasForeignKey("TagId"); - }); - - 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.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) - .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/20250614173150_UserChanges.Designer.cs b/Watcher/Migrations/20250614173150_UserChanges.Designer.cs deleted file mode 100644 index dd22ffb..0000000 --- a/Watcher/Migrations/20250614173150_UserChanges.Designer.cs +++ /dev/null @@ -1,278 +0,0 @@ -// -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("20250614173150_UserChanges")] - partial class UserChanges - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 64); - - modelBuilder.Entity("Watcher.Models.Container", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime(6)"); - - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("ImageId") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("TagId") - .HasColumnType("int"); - - b.Property("Type") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.HasIndex("ImageId"); - - b.HasIndex("TagId"); - - b.ToTable("Containers"); - }); - - modelBuilder.Entity("Watcher.Models.Image", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("Name") - .HasColumnType("longtext"); - - b.Property("Tag") - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Images"); - }); - - modelBuilder.Entity("Watcher.Models.LogEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("ContainerId") - .HasColumnType("int"); - - b.Property("Level") - .HasColumnType("longtext"); - - b.Property("Message") - .HasColumnType("longtext"); - - b.Property("ServerId") - .HasColumnType("int"); - - b.Property("Timestamp") - .HasColumnType("datetime(6)"); - - b.HasKey("Id"); - - b.HasIndex("ContainerId"); - - b.HasIndex("ServerId"); - - b.ToTable("LogEvents"); - }); - - modelBuilder.Entity("Watcher.Models.Metric", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("ContainerId") - .HasColumnType("int"); - - b.Property("ServerId") - .HasColumnType("int"); - - b.Property("Timestamp") - .HasColumnType("datetime(6)"); - - b.Property("Type") - .HasColumnType("longtext"); - - b.Property("Value") - .HasColumnType("double"); - - b.HasKey("Id"); - - b.HasIndex("ContainerId"); - - b.HasIndex("ServerId"); - - b.ToTable("Metrics"); - }); - - modelBuilder.Entity("Watcher.Models.Server", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime(6)"); - - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Name") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("TagId") - .HasColumnType("int"); - - b.Property("Type") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.HasIndex("TagId"); - - b.ToTable("Servers"); - }); - - modelBuilder.Entity("Watcher.Models.Tag", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("Name") - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Tags"); - }); - - modelBuilder.Entity("Watcher.Models.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("Email") - .HasColumnType("longtext"); - - b.Property("LastLogin") - .HasColumnType("datetime(6)"); - - b.Property("PocketId") - .IsRequired() - .HasColumnType("longtext"); - - b.Property("PreferredUsername") - .IsRequired() - .HasColumnType("longtext"); - - b.HasKey("Id"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("Watcher.Models.Container", b => - { - b.HasOne("Watcher.Models.Image", null) - .WithMany("Containers") - .HasForeignKey("ImageId"); - - b.HasOne("Watcher.Models.Tag", null) - .WithMany("Containers") - .HasForeignKey("TagId"); - }); - - 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.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) - .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/20250614173150_UserChanges.cs b/Watcher/Migrations/20250614173150_UserChanges.cs deleted file mode 100644 index e288a35..0000000 --- a/Watcher/Migrations/20250614173150_UserChanges.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Watcher.Migrations -{ - /// - public partial class UserChanges : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.RenameColumn( - name: "Role", - table: "Users", - newName: "PreferredUsername"); - - migrationBuilder.UpdateData( - table: "Users", - keyColumn: "PocketId", - keyValue: null, - column: "PocketId", - value: ""); - - migrationBuilder.AlterColumn( - name: "PocketId", - table: "Users", - type: "longtext", - nullable: false, - oldClrType: typeof(string), - oldType: "longtext", - oldNullable: true) - .Annotation("MySql:CharSet", "utf8mb4") - .OldAnnotation("MySql:CharSet", "utf8mb4"); - - migrationBuilder.AddColumn( - name: "Email", - table: "Users", - type: "longtext", - nullable: true) - .Annotation("MySql:CharSet", "utf8mb4"); - - migrationBuilder.AddColumn( - name: "LastLogin", - table: "Users", - type: "datetime(6)", - nullable: false, - defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Email", - table: "Users"); - - migrationBuilder.DropColumn( - name: "LastLogin", - table: "Users"); - - migrationBuilder.RenameColumn( - name: "PreferredUsername", - table: "Users", - newName: "Role"); - - migrationBuilder.AlterColumn( - name: "PocketId", - table: "Users", - type: "longtext", - nullable: true, - oldClrType: typeof(string), - oldType: "longtext") - .Annotation("MySql:CharSet", "utf8mb4") - .OldAnnotation("MySql:CharSet", "utf8mb4"); - } - } -} diff --git a/Watcher/Migrations/20250614183243_Server-Container-IsRunning-Value.cs b/Watcher/Migrations/20250614183243_Server-Container-IsRunning-Value.cs deleted file mode 100644 index e6c9cab..0000000 --- a/Watcher/Migrations/20250614183243_Server-Container-IsRunning-Value.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Watcher.Migrations -{ - /// - public partial class ServerContainerIsRunningValue : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "IsOnline", - table: "Servers", - type: "tinyint(1)", - nullable: false, - defaultValue: false); - - migrationBuilder.AddColumn( - name: "IsRunning", - table: "Containers", - type: "tinyint(1)", - nullable: false, - defaultValue: false); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "IsOnline", - table: "Servers"); - - migrationBuilder.DropColumn( - name: "IsRunning", - table: "Containers"); - } - } -} diff --git a/Watcher/Migrations/20250615102649_ServerAnpassung.cs b/Watcher/Migrations/20250615102649_ServerAnpassung.cs deleted file mode 100644 index c8e9931..0000000 --- a/Watcher/Migrations/20250615102649_ServerAnpassung.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Watcher.Migrations -{ - /// - public partial class ServerAnpassung : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "LastSeen", - table: "Servers", - type: "datetime(6)", - nullable: false, - defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "LastSeen", - table: "Servers"); - } - } -} diff --git a/Watcher/Migrations/20250615114821_ServerCleanUp.cs b/Watcher/Migrations/20250615114821_ServerCleanUp.cs deleted file mode 100644 index 3d03083..0000000 --- a/Watcher/Migrations/20250615114821_ServerCleanUp.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Watcher.Migrations -{ - /// - public partial class ServerCleanUp : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Hostname", - table: "Servers"); - - migrationBuilder.DropColumn( - name: "Status", - table: "Servers"); - - migrationBuilder.AddColumn( - name: "Description", - table: "Servers", - type: "longtext", - nullable: true) - .Annotation("MySql:CharSet", "utf8mb4"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Description", - table: "Servers"); - - migrationBuilder.AddColumn( - name: "Hostname", - table: "Servers", - type: "longtext", - nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"); - - migrationBuilder.AddColumn( - name: "Status", - table: "Servers", - type: "longtext", - nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"); - } - } -} diff --git a/Watcher/Migrations/20250615114821_ServerCleanUp.Designer.cs b/Watcher/Migrations/20250617153602_InitialMigration.Designer.cs similarity index 94% rename from Watcher/Migrations/20250615114821_ServerCleanUp.Designer.cs rename to Watcher/Migrations/20250617153602_InitialMigration.Designer.cs index 98add17..5d549f0 100644 --- a/Watcher/Migrations/20250615114821_ServerCleanUp.Designer.cs +++ b/Watcher/Migrations/20250617153602_InitialMigration.Designer.cs @@ -11,8 +11,8 @@ using Watcher.Data; namespace Watcher.Migrations { [DbContext(typeof(AppDbContext))] - [Migration("20250615114821_ServerCleanUp")] - partial class ServerCleanUp + [Migration("20250617153602_InitialMigration")] + partial class InitialMigration { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -148,12 +148,21 @@ namespace Watcher.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + b.Property("CpuCores") + .HasColumnType("int"); + + b.Property("CpuType") + .HasColumnType("longtext"); + b.Property("CreatedAt") .HasColumnType("datetime(6)"); b.Property("Description") .HasColumnType("longtext"); + b.Property("GpuType") + .HasColumnType("longtext"); + b.Property("IPAddress") .IsRequired() .HasColumnType("longtext"); @@ -168,6 +177,9 @@ namespace Watcher.Migrations .IsRequired() .HasColumnType("longtext"); + b.Property("RamSize") + .HasColumnType("double"); + b.Property("TagId") .HasColumnType("int"); diff --git a/Watcher/Migrations/20250614155203_InitialModelsAdded_1.cs b/Watcher/Migrations/20250617153602_InitialMigration.cs similarity index 59% rename from Watcher/Migrations/20250614155203_InitialModelsAdded_1.cs rename to Watcher/Migrations/20250617153602_InitialMigration.cs index ac7f668..e8bc8fd 100644 --- a/Watcher/Migrations/20250614155203_InitialModelsAdded_1.cs +++ b/Watcher/Migrations/20250617153602_InitialMigration.cs @@ -7,28 +7,13 @@ using Microsoft.EntityFrameworkCore.Migrations; namespace Watcher.Migrations { /// - public partial class InitialModelsAdded_1 : Migration + public partial class InitialMigration : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) { - migrationBuilder.AddColumn( - name: "TagId", - table: "Servers", - type: "int", - nullable: true); - - migrationBuilder.AddColumn( - name: "ImageId", - table: "Containers", - type: "int", - nullable: true); - - migrationBuilder.AddColumn( - name: "TagId", - table: "Containers", - type: "int", - nullable: true); + migrationBuilder.AlterDatabase() + .Annotation("MySql:CharSet", "utf8mb4"); migrationBuilder.CreateTable( name: "Images", @@ -47,6 +32,112 @@ namespace Watcher.Migrations }) .Annotation("MySql:CharSet", "utf8mb4"); + migrationBuilder.CreateTable( + name: "Tags", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Name = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_Tags", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + PocketId = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + PreferredUsername = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Email = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + LastLogin = table.Column(type: "datetime(6)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Containers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Name = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Status = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ImageId = table.Column(type: "int", nullable: true), + CreatedAt = table.Column(type: "datetime(6)", nullable: false), + Hostname = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Type = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + IsRunning = table.Column(type: "tinyint(1)", nullable: false), + TagId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Containers", x => x.Id); + table.ForeignKey( + name: "FK_Containers_Images_ImageId", + column: x => x.ImageId, + principalTable: "Images", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Containers_Tags_TagId", + column: x => x.TagId, + principalTable: "Tags", + principalColumn: "Id"); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Servers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Name = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + IPAddress = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + CreatedAt = table.Column(type: "datetime(6)", nullable: false), + Type = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + IsOnline = table.Column(type: "tinyint(1)", nullable: false), + LastSeen = table.Column(type: "datetime(6)", nullable: false), + Description = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + CpuType = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + CpuCores = table.Column(type: "int", nullable: false), + GpuType = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + RamSize = table.Column(type: "double", nullable: false), + TagId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Servers", x => x.Id); + table.ForeignKey( + name: "FK_Servers_Tags_TagId", + column: x => x.TagId, + principalTable: "Tags", + principalColumn: "Id"); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + migrationBuilder.CreateTable( name: "LogEvents", columns: table => new @@ -106,43 +197,6 @@ namespace Watcher.Migrations }) .Annotation("MySql:CharSet", "utf8mb4"); - migrationBuilder.CreateTable( - name: "Tags", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), - Name = table.Column(type: "longtext", nullable: true) - .Annotation("MySql:CharSet", "utf8mb4") - }, - constraints: table => - { - table.PrimaryKey("PK_Tags", x => x.Id); - }) - .Annotation("MySql:CharSet", "utf8mb4"); - - migrationBuilder.CreateTable( - name: "Users", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), - PocketId = table.Column(type: "longtext", nullable: true) - .Annotation("MySql:CharSet", "utf8mb4"), - Role = table.Column(type: "longtext", nullable: false) - .Annotation("MySql:CharSet", "utf8mb4") - }, - constraints: table => - { - table.PrimaryKey("PK_Users", x => x.Id); - }) - .Annotation("MySql:CharSet", "utf8mb4"); - - migrationBuilder.CreateIndex( - name: "IX_Servers_TagId", - table: "Servers", - column: "TagId"); - migrationBuilder.CreateIndex( name: "IX_Containers_ImageId", table: "Containers", @@ -173,81 +227,35 @@ namespace Watcher.Migrations table: "Metrics", column: "ServerId"); - migrationBuilder.AddForeignKey( - name: "FK_Containers_Images_ImageId", - table: "Containers", - column: "ImageId", - principalTable: "Images", - principalColumn: "Id"); - - migrationBuilder.AddForeignKey( - name: "FK_Containers_Tags_TagId", - table: "Containers", - column: "TagId", - principalTable: "Tags", - principalColumn: "Id"); - - migrationBuilder.AddForeignKey( - name: "FK_Servers_Tags_TagId", + migrationBuilder.CreateIndex( + name: "IX_Servers_TagId", table: "Servers", - column: "TagId", - principalTable: "Tags", - principalColumn: "Id"); + column: "TagId"); } /// protected override void Down(MigrationBuilder migrationBuilder) { - migrationBuilder.DropForeignKey( - name: "FK_Containers_Images_ImageId", - table: "Containers"); - - migrationBuilder.DropForeignKey( - name: "FK_Containers_Tags_TagId", - table: "Containers"); - - migrationBuilder.DropForeignKey( - name: "FK_Servers_Tags_TagId", - table: "Servers"); - - migrationBuilder.DropTable( - name: "Images"); - migrationBuilder.DropTable( name: "LogEvents"); migrationBuilder.DropTable( name: "Metrics"); - migrationBuilder.DropTable( - name: "Tags"); - migrationBuilder.DropTable( name: "Users"); - migrationBuilder.DropIndex( - name: "IX_Servers_TagId", - table: "Servers"); + migrationBuilder.DropTable( + name: "Containers"); - migrationBuilder.DropIndex( - name: "IX_Containers_ImageId", - table: "Containers"); + migrationBuilder.DropTable( + name: "Servers"); - migrationBuilder.DropIndex( - name: "IX_Containers_TagId", - table: "Containers"); + migrationBuilder.DropTable( + name: "Images"); - migrationBuilder.DropColumn( - name: "TagId", - table: "Servers"); - - migrationBuilder.DropColumn( - name: "ImageId", - table: "Containers"); - - migrationBuilder.DropColumn( - name: "TagId", - table: "Containers"); + migrationBuilder.DropTable( + name: "Tags"); } } } diff --git a/Watcher/Migrations/20250615102649_ServerAnpassung.Designer.cs b/Watcher/Migrations/20250617165126_ServerPrimaryKey.Designer.cs similarity index 72% rename from Watcher/Migrations/20250615102649_ServerAnpassung.Designer.cs rename to Watcher/Migrations/20250617165126_ServerPrimaryKey.Designer.cs index acd59d2..14cf440 100644 --- a/Watcher/Migrations/20250615102649_ServerAnpassung.Designer.cs +++ b/Watcher/Migrations/20250617165126_ServerPrimaryKey.Designer.cs @@ -11,50 +11,48 @@ using Watcher.Data; namespace Watcher.Migrations { [DbContext(typeof(AppDbContext))] - [Migration("20250615102649_ServerAnpassung")] - partial class ServerAnpassung + [Migration("20250617165126_ServerPrimaryKey")] + partial class ServerPrimaryKey { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 64); + modelBuilder.HasAnnotation("ProductVersion", "8.0.6"); modelBuilder.Entity("Watcher.Models.Container", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("CreatedAt") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.Property("Hostname") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("ImageId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("IsRunning") - .HasColumnType("tinyint(1)"); + .HasColumnType("INTEGER"); b.Property("Name") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Status") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("TagId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Type") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -69,13 +67,13 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Name") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Tag") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -86,22 +84,22 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("ContainerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Level") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Message") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("ServerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Timestamp") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -116,22 +114,22 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("ContainerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("ServerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Timestamp") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.Property("Type") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Value") - .HasColumnType("double"); + .HasColumnType("REAL"); b.HasKey("Id"); @@ -146,39 +144,46 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); + + b.Property("CpuCores") + .HasColumnType("INTEGER"); + + b.Property("CpuType") + .HasColumnType("TEXT"); b.Property("CreatedAt") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("GpuType") + .HasColumnType("TEXT"); b.Property("IPAddress") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("IsOnline") - .HasColumnType("tinyint(1)"); + .HasColumnType("INTEGER"); b.Property("LastSeen") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.Property("Name") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); + b.Property("RamSize") + .HasColumnType("REAL"); b.Property("TagId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Type") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -191,10 +196,10 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Name") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -205,21 +210,21 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Email") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("LastLogin") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.Property("PocketId") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("PreferredUsername") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); diff --git a/Watcher/Migrations/20250617165126_ServerPrimaryKey.cs b/Watcher/Migrations/20250617165126_ServerPrimaryKey.cs new file mode 100644 index 0000000..f258b61 --- /dev/null +++ b/Watcher/Migrations/20250617165126_ServerPrimaryKey.cs @@ -0,0 +1,785 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Watcher.Migrations +{ + /// + public partial class ServerPrimaryKey : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "PreferredUsername", + table: "Users", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "longtext"); + + migrationBuilder.AlterColumn( + name: "PocketId", + table: "Users", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "longtext"); + + migrationBuilder.AlterColumn( + name: "LastLogin", + table: "Users", + type: "TEXT", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime(6)"); + + migrationBuilder.AlterColumn( + name: "Email", + table: "Users", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Users", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Tags", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Tags", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Type", + table: "Servers", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "longtext"); + + migrationBuilder.AlterColumn( + name: "TagId", + table: "Servers", + type: "INTEGER", + nullable: true, + oldClrType: typeof(int), + oldType: "int", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "RamSize", + table: "Servers", + type: "REAL", + nullable: false, + oldClrType: typeof(double), + oldType: "double"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Servers", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "longtext"); + + migrationBuilder.AlterColumn( + name: "LastSeen", + table: "Servers", + type: "TEXT", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime(6)"); + + migrationBuilder.AlterColumn( + name: "IsOnline", + table: "Servers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(bool), + oldType: "tinyint(1)"); + + migrationBuilder.AlterColumn( + name: "IPAddress", + table: "Servers", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "longtext"); + + migrationBuilder.AlterColumn( + name: "GpuType", + table: "Servers", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Description", + table: "Servers", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Servers", + type: "TEXT", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime(6)"); + + migrationBuilder.AlterColumn( + name: "CpuType", + table: "Servers", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CpuCores", + table: "Servers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "int"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Servers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Value", + table: "Metrics", + type: "REAL", + nullable: false, + oldClrType: typeof(double), + oldType: "double"); + + migrationBuilder.AlterColumn( + name: "Type", + table: "Metrics", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Timestamp", + table: "Metrics", + type: "TEXT", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime(6)"); + + migrationBuilder.AlterColumn( + name: "ServerId", + table: "Metrics", + type: "INTEGER", + nullable: true, + oldClrType: typeof(int), + oldType: "int", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ContainerId", + table: "Metrics", + type: "INTEGER", + nullable: true, + oldClrType: typeof(int), + oldType: "int", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Metrics", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Timestamp", + table: "LogEvents", + type: "TEXT", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime(6)"); + + migrationBuilder.AlterColumn( + name: "ServerId", + table: "LogEvents", + type: "INTEGER", + nullable: true, + oldClrType: typeof(int), + oldType: "int", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Message", + table: "LogEvents", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Level", + table: "LogEvents", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ContainerId", + table: "LogEvents", + type: "INTEGER", + nullable: true, + oldClrType: typeof(int), + oldType: "int", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "LogEvents", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Tag", + table: "Images", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Images", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Images", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Type", + table: "Containers", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "longtext"); + + migrationBuilder.AlterColumn( + name: "TagId", + table: "Containers", + type: "INTEGER", + nullable: true, + oldClrType: typeof(int), + oldType: "int", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Status", + table: "Containers", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "longtext"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Containers", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "longtext"); + + migrationBuilder.AlterColumn( + name: "IsRunning", + table: "Containers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(bool), + oldType: "tinyint(1)"); + + migrationBuilder.AlterColumn( + name: "ImageId", + table: "Containers", + type: "INTEGER", + nullable: true, + oldClrType: typeof(int), + oldType: "int", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Hostname", + table: "Containers", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "longtext"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Containers", + type: "TEXT", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime(6)"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Containers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "PreferredUsername", + table: "Users", + type: "longtext", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "PocketId", + table: "Users", + type: "longtext", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "LastLogin", + table: "Users", + type: "datetime(6)", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "Email", + table: "Users", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Users", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Tags", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Tags", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Type", + table: "Servers", + type: "longtext", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "TagId", + table: "Servers", + type: "int", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "RamSize", + table: "Servers", + type: "double", + nullable: false, + oldClrType: typeof(double), + oldType: "REAL"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Servers", + type: "longtext", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "LastSeen", + table: "Servers", + type: "datetime(6)", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "IsOnline", + table: "Servers", + type: "tinyint(1)", + nullable: false, + oldClrType: typeof(bool), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "IPAddress", + table: "Servers", + type: "longtext", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "GpuType", + table: "Servers", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Description", + table: "Servers", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Servers", + type: "datetime(6)", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "CpuType", + table: "Servers", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CpuCores", + table: "Servers", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Servers", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Value", + table: "Metrics", + type: "double", + nullable: false, + oldClrType: typeof(double), + oldType: "REAL"); + + migrationBuilder.AlterColumn( + name: "Type", + table: "Metrics", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Timestamp", + table: "Metrics", + type: "datetime(6)", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "ServerId", + table: "Metrics", + type: "int", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ContainerId", + table: "Metrics", + type: "int", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Metrics", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Timestamp", + table: "LogEvents", + type: "datetime(6)", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "ServerId", + table: "LogEvents", + type: "int", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Message", + table: "LogEvents", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Level", + table: "LogEvents", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ContainerId", + table: "LogEvents", + type: "int", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "LogEvents", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Tag", + table: "Images", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Images", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Images", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "Type", + table: "Containers", + type: "longtext", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "TagId", + table: "Containers", + type: "int", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Status", + table: "Containers", + type: "longtext", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Containers", + type: "longtext", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "IsRunning", + table: "Containers", + type: "tinyint(1)", + nullable: false, + oldClrType: typeof(bool), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "ImageId", + table: "Containers", + type: "int", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Hostname", + table: "Containers", + type: "longtext", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Containers", + type: "datetime(6)", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Containers", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .Annotation("Sqlite:Autoincrement", true) + .OldAnnotation("Sqlite:Autoincrement", true); + } + } +} diff --git a/Watcher/Migrations/20250614224113_Container-Server-Update.Designer.cs b/Watcher/Migrations/20250617174242_UserPasswordAdded.Designer.cs similarity index 70% rename from Watcher/Migrations/20250614224113_Container-Server-Update.Designer.cs rename to Watcher/Migrations/20250617174242_UserPasswordAdded.Designer.cs index 0ac9bbe..123e1fa 100644 --- a/Watcher/Migrations/20250614224113_Container-Server-Update.Designer.cs +++ b/Watcher/Migrations/20250617174242_UserPasswordAdded.Designer.cs @@ -11,50 +11,48 @@ using Watcher.Data; namespace Watcher.Migrations { [DbContext(typeof(AppDbContext))] - [Migration("20250614224113_Container-Server-Update")] - partial class ContainerServerUpdate + [Migration("20250617174242_UserPasswordAdded")] + partial class UserPasswordAdded { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 64); + modelBuilder.HasAnnotation("ProductVersion", "8.0.6"); modelBuilder.Entity("Watcher.Models.Container", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("CreatedAt") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.Property("Hostname") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("ImageId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("IsRunning") - .HasColumnType("tinyint(1)"); + .HasColumnType("INTEGER"); b.Property("Name") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Status") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("TagId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Type") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -69,13 +67,13 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Name") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Tag") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -86,22 +84,22 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("ContainerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Level") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Message") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("ServerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Timestamp") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -116,22 +114,22 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("ContainerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("ServerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Timestamp") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.Property("Type") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Value") - .HasColumnType("double"); + .HasColumnType("REAL"); b.HasKey("Id"); @@ -146,36 +144,46 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); + + b.Property("CpuCores") + .HasColumnType("INTEGER"); + + b.Property("CpuType") + .HasColumnType("TEXT"); b.Property("CreatedAt") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); - b.Property("Hostname") - .IsRequired() - .HasColumnType("longtext"); + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("GpuType") + .HasColumnType("TEXT"); b.Property("IPAddress") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("IsOnline") - .HasColumnType("tinyint(1)"); + .HasColumnType("INTEGER"); + + b.Property("LastSeen") + .HasColumnType("TEXT"); b.Property("Name") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); + b.Property("RamSize") + .HasColumnType("REAL"); b.Property("TagId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Type") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -188,10 +196,10 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Name") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -202,21 +210,29 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Email") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); + + b.Property("IdentityProvider") + .IsRequired() + .HasColumnType("TEXT"); b.Property("LastLogin") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); b.Property("PocketId") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("PreferredUsername") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); diff --git a/Watcher/Migrations/20250617174242_UserPasswordAdded.cs b/Watcher/Migrations/20250617174242_UserPasswordAdded.cs new file mode 100644 index 0000000..04ef332 --- /dev/null +++ b/Watcher/Migrations/20250617174242_UserPasswordAdded.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Watcher.Migrations +{ + /// + public partial class UserPasswordAdded : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IdentityProvider", + table: "Users", + type: "TEXT", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Password", + table: "Users", + type: "TEXT", + nullable: false, + defaultValue: ""); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IdentityProvider", + table: "Users"); + + migrationBuilder.DropColumn( + name: "Password", + table: "Users"); + } + } +} diff --git a/Watcher/Migrations/20250614183243_Server-Container-IsRunning-Value.Designer.cs b/Watcher/Migrations/20250621124832_DB-Update Issue#32.Designer.cs similarity index 57% rename from Watcher/Migrations/20250614183243_Server-Container-IsRunning-Value.Designer.cs rename to Watcher/Migrations/20250621124832_DB-Update Issue#32.Designer.cs index 60f4cfb..e8cad36 100644 --- a/Watcher/Migrations/20250614183243_Server-Container-IsRunning-Value.Designer.cs +++ b/Watcher/Migrations/20250621124832_DB-Update Issue#32.Designer.cs @@ -11,50 +11,48 @@ using Watcher.Data; namespace Watcher.Migrations { [DbContext(typeof(AppDbContext))] - [Migration("20250614183243_Server-Container-IsRunning-Value")] - partial class ServerContainerIsRunningValue + [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") - .HasAnnotation("Relational:MaxIdentifierLength", 64); + modelBuilder.HasAnnotation("ProductVersion", "8.0.6"); modelBuilder.Entity("Watcher.Models.Container", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("CreatedAt") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.Property("Hostname") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("ImageId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("IsRunning") - .HasColumnType("tinyint(1)"); + .HasColumnType("INTEGER"); b.Property("Name") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Status") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("TagId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Type") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -69,13 +67,13 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Name") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Tag") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -86,22 +84,22 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("ContainerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Level") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Message") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("ServerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Timestamp") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -116,29 +114,55 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); - b.Property("ContainerId") - .HasColumnType("int"); + 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("int"); + .HasColumnType("INTEGER"); b.Property("Timestamp") - .HasColumnType("datetime(6)"); - - b.Property("Type") - .HasColumnType("longtext"); - - b.Property("Value") - .HasColumnType("double"); + .HasColumnType("TEXT"); b.HasKey("Id"); - b.HasIndex("ContainerId"); - - b.HasIndex("ServerId"); - b.ToTable("Metrics"); }); @@ -146,32 +170,46 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); + + b.Property("CpuCores") + .HasColumnType("INTEGER"); + + b.Property("CpuType") + .HasColumnType("TEXT"); b.Property("CreatedAt") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); - b.Property("Hostname") + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("GpuType") + .HasColumnType("TEXT"); + + b.Property("IPAddress") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("IsOnline") - .HasColumnType("tinyint(1)"); + .HasColumnType("INTEGER"); + + b.Property("LastSeen") + .HasColumnType("TEXT"); b.Property("Name") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); - b.Property("Status") - .IsRequired() - .HasColumnType("longtext"); + b.Property("RamSize") + .HasColumnType("REAL"); b.Property("TagId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Type") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -184,10 +222,10 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Name") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -198,21 +236,28 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Email") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); + + b.Property("IdentityProvider") + .IsRequired() + .HasColumnType("TEXT"); b.Property("LastLogin") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); - b.Property("PocketId") - .IsRequired() - .HasColumnType("longtext"); + b.Property("OIDC_Id") + .HasColumnType("TEXT"); - b.Property("PreferredUsername") + b.Property("Password") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -221,13 +266,15 @@ namespace Watcher.Migrations modelBuilder.Entity("Watcher.Models.Container", b => { - b.HasOne("Watcher.Models.Image", null) + 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 => @@ -245,21 +292,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/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/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/20250614224113_Container-Server-Update.cs b/Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.cs similarity index 61% rename from Watcher/Migrations/20250614224113_Container-Server-Update.cs rename to Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.cs index b485dfd..974f389 100644 --- a/Watcher/Migrations/20250614224113_Container-Server-Update.cs +++ b/Watcher/Migrations/20250621125157_DB-Update Issue#32 IsVerified-Servers.cs @@ -5,24 +5,24 @@ namespace Watcher.Migrations { /// - public partial class ContainerServerUpdate : Migration + public partial class DBUpdateIssue32IsVerifiedServers : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) { - migrationBuilder.AddColumn( - name: "IPAddress", + migrationBuilder.AddColumn( + name: "IsVerified", table: "Servers", - type: "longtext", - nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"); + type: "INTEGER", + nullable: false, + defaultValue: false); } /// protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropColumn( - name: "IPAddress", + name: "IsVerified", table: "Servers"); } } diff --git a/Watcher/Migrations/AppDbContextModelSnapshot.cs b/Watcher/Migrations/AppDbContextModelSnapshot.cs index 1117443..11d908f 100644 --- a/Watcher/Migrations/AppDbContextModelSnapshot.cs +++ b/Watcher/Migrations/AppDbContextModelSnapshot.cs @@ -15,43 +15,41 @@ namespace Watcher.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.6") - .HasAnnotation("Relational:MaxIdentifierLength", 64); + modelBuilder.HasAnnotation("ProductVersion", "8.0.6"); modelBuilder.Entity("Watcher.Models.Container", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("CreatedAt") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.Property("Hostname") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("ImageId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("IsRunning") - .HasColumnType("tinyint(1)"); + .HasColumnType("INTEGER"); b.Property("Name") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Status") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("TagId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Type") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -66,13 +64,13 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Name") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Tag") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -83,22 +81,22 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("ContainerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Level") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("Message") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("ServerId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Timestamp") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -113,29 +111,55 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); - b.Property("ContainerId") - .HasColumnType("int"); + 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("int"); + .HasColumnType("INTEGER"); b.Property("Timestamp") - .HasColumnType("datetime(6)"); - - b.Property("Type") - .HasColumnType("longtext"); - - b.Property("Value") - .HasColumnType("double"); + .HasColumnType("TEXT"); b.HasKey("Id"); - b.HasIndex("ContainerId"); - - b.HasIndex("ServerId"); - b.ToTable("Metrics"); }); @@ -143,34 +167,49 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); + + b.Property("CpuCores") + .HasColumnType("INTEGER"); + + b.Property("CpuType") + .HasColumnType("TEXT"); b.Property("CreatedAt") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.Property("Description") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); + + b.Property("GpuType") + .HasColumnType("TEXT"); b.Property("IPAddress") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.Property("IsOnline") - .HasColumnType("tinyint(1)"); + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); b.Property("LastSeen") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); b.Property("Name") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); + + b.Property("RamSize") + .HasColumnType("REAL"); b.Property("TagId") - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Type") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -183,10 +222,10 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Name") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -197,21 +236,28 @@ namespace Watcher.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("INTEGER"); b.Property("Email") - .HasColumnType("longtext"); + .HasColumnType("TEXT"); + + b.Property("IdentityProvider") + .IsRequired() + .HasColumnType("TEXT"); b.Property("LastLogin") - .HasColumnType("datetime(6)"); + .HasColumnType("TEXT"); - b.Property("PocketId") - .IsRequired() - .HasColumnType("longtext"); + b.Property("OIDC_Id") + .HasColumnType("TEXT"); - b.Property("PreferredUsername") + b.Property("Password") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); b.HasKey("Id"); @@ -246,21 +292,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 84a2f9d..83466a8 100644 --- a/Watcher/Models/Server.cs +++ b/Watcher/Models/Server.cs @@ -1,23 +1,39 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + 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 required string Type { get; set; } + + public string? Description { get; set; } = String.Empty; + + + // Hardware Infos + public string? CpuType { get; set; } = string.Empty; + public int CpuCores { get; set; } = 0; + public string? GpuType { get; set; } = string.Empty; + public double RamSize { get; set; } = 0; + + + // Database public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - // z.B. "VPS", "standalone", "VM", etc. - public string Type { get; set; } = "VPS"; - public Boolean IsOnline { get; set; } = false; public DateTime LastSeen { get; set; } - public string? Description { get; set; } - + public Boolean IsVerified { get; set; } = false; } diff --git a/Watcher/Models/User.cs b/Watcher/Models/User.cs index 12903fc..13d366a 100644 --- a/Watcher/Models/User.cs +++ b/Watcher/Models/User.cs @@ -1,10 +1,22 @@ +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; } + + [Required] + public string IdentityProvider { get; set; } = "local"; + + [Required] + [DataType(DataType.Password)] + public String? Password { get; set; } = string.Empty; } diff --git a/Watcher/Program.cs b/Watcher/Program.cs index a2e01b4..baba787 100644 --- a/Watcher/Program.cs +++ b/Watcher/Program.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Sqlite; using Microsoft.IdentityModel.Tokens; using Watcher.Data; using Watcher.Models; @@ -14,32 +15,63 @@ builder.Services.AddControllersWithViews(); // HttpContentAccessor builder.Services.AddHttpContextAccessor(); -// ---------- Konfiguration laden ---------- +// ---------- Konfiguration ---------- +DotNetEnv.Env.Load(); + +builder.Configuration + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .AddEnvironmentVariables(); + +// Konfiguration laden var configuration = builder.Configuration; -// ---------- DB-Kontext mit MySQL ---------- -builder.Services.AddDbContext(options => - options.UseMySql( - configuration.GetConnectionString("DefaultConnection"), - ServerVersion.AutoDetect(configuration.GetConnectionString("DefaultConnection")) - ) -); +// ---------- DB-Kontext ---------- + +var dbProvider = configuration["Database:Provider"] ?? "MySQL"; +var connectionString = configuration["Database:ConnectionString"]; + +builder.Services.AddDbContext((serviceProvider, options) => +{ + var config = serviceProvider.GetRequiredService(); + var provider = dbProvider; + + if (provider == "MySql") + { + var connStr = config.GetConnectionString("MySql") ?? config["Database:ConnectionStrings:MySql"]; + options.UseMySql(connStr, ServerVersion.AutoDetect(connStr)); + } + else if (provider == "Sqlite") + { + var connStr = config.GetConnectionString("Sqlite") ?? config["Database:ConnectionStrings:Sqlite"]; + options.UseSqlite(connStr); + } + else + { + throw new Exception("Unsupported database provider configured."); + } +}); // ---------- Authentifizierung konfigurieren ---------- -builder.Services.AddAuthentication(options => +// PocketID nur konfigurieren, wenn aktiviert +var pocketIdSection = builder.Configuration.GetSection("Authentication:PocketID"); +var pocketIdEnabled = pocketIdSection.GetValue("Enabled"); + +var auth = builder.Services.AddAuthentication("Cookies"); + +auth.AddCookie("Cookies", options => { - options.DefaultScheme = "Cookies"; - options.DefaultChallengeScheme = "oidc"; -}) -.AddCookie("Cookies") + options.LoginPath = "/Auth/Login"; + options.AccessDeniedPath = "/Auth/AccessDenied"; +}); + +builder.Services.AddAuthentication() .AddOpenIdConnect("oidc", options => { - var config = builder.Configuration.GetSection("Authentication:PocketID"); - options.Authority = config["Authority"]; - options.ClientId = config["ClientId"]; - options.ClientSecret = config["ClientSecret"]; + options.Authority = pocketIdSection["Authority"]; + options.ClientId = pocketIdSection["ClientId"]; + options.ClientSecret = pocketIdSection["ClientSecret"]; options.ResponseType = "code"; - options.CallbackPath = config["CallbackPath"]; + options.CallbackPath = pocketIdSection["CallbackPath"]; options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; @@ -48,51 +80,95 @@ builder.Services.AddAuthentication(options => options.Scope.Add("openid"); options.Scope.Add("profile"); options.Scope.Add("email"); - + options.Events = new OpenIdConnectEvents -{ - OnTokenValidated = async ctx => { - var db = ctx.HttpContext.RequestServices.GetRequiredService(); - - var principal = ctx.Principal; - var pocketId = principal.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value; - var preferredUsername = principal.FindFirst("preferred_username")?.Value; - var email = principal.FindFirst("email")?.Value; - - if (string.IsNullOrEmpty(pocketId)) - return; - - var user = await db.Users.FirstOrDefaultAsync(u => u.PocketId == pocketId); - - if (user == null) + OnTokenValidated = async ctx => { - user = new User + var db = ctx.HttpContext.RequestServices.GetRequiredService(); + + var principal = ctx.Principal; + var pocketId = principal.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value; + var preferredUsername = principal.FindFirst("preferred_username")?.Value; + var email = principal.FindFirst("email")?.Value; + + if (string.IsNullOrEmpty(pocketId)) + return; + + var user = await db.Users.FirstOrDefaultAsync(u => u.OIDC_Id == pocketId); + + if (user == null) { - PocketId = pocketId, - PreferredUsername = preferredUsername ?? "", - Email = email, - LastLogin = DateTime.UtcNow - }; - db.Users.Add(user); - } - else - { - user.LastLogin = DateTime.UtcNow; - user.PreferredUsername = preferredUsername ?? user.PreferredUsername; - user.Email = email ?? user.Email; - db.Users.Update(user); - } - - await db.SaveChangesAsync(); - } -}; + user = new User + { + OIDC_Id = pocketId, + Username = preferredUsername ?? "", + Email = email, + LastLogin = DateTime.UtcNow, + IdentityProvider = "oidc", + Password = string.Empty + }; + db.Users.Add(user); + } + else + { + user.LastLogin = DateTime.UtcNow; + user.Username = preferredUsername ?? user.Username; + user.Email = email ?? user.Email; + db.Users.Update(user); + } + await db.SaveChangesAsync(); + } + }; }); + + var app = builder.Build(); + + +// Migrationen anwenden (für SQLite oder andere DBs) +using (var scope = app.Services.CreateScope()) +{ + var db = scope.ServiceProvider.GetRequiredService(); + db.Database.Migrate(); +} + + +// Standart-User in Datenbank schreiben +using (var scope = app.Services.CreateScope()) +{ + var db = scope.ServiceProvider.GetRequiredService(); + + Console.WriteLine("Checking for users..."); + + if (!db.Users.Any()) + { + Console.WriteLine("No users found, creating default user..."); + + var defaultUser = new User + { + OIDC_Id = string.Empty, + Username = "admin", + Email = string.Empty, + LastLogin = DateTime.UtcNow, + IdentityProvider = "local", + Password = BCrypt.Net.BCrypt.HashPassword("changeme") + }; + db.Users.Add(defaultUser); + db.SaveChanges(); + + Console.WriteLine("Default user created."); + } + else + { + Console.WriteLine("Users already exist."); + } +} + // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { @@ -101,6 +177,11 @@ if (!app.Environment.IsDevelopment()) app.UseHsts(); } + + + + + app.UseHttpsRedirection(); app.UseRouting(); @@ -112,7 +193,7 @@ app.UseStaticFiles(); app.MapControllerRoute( name: "default", - pattern: "{controller=Home}/{action=Index}/{id?}" + pattern: "{controller=Auth}/{action=Login}/" ); diff --git a/Watcher/ViewModels/EditUserSettingsViewModel.cs b/Watcher/ViewModels/EditUserSettingsViewModel.cs new file mode 100644 index 0000000..468cc86 --- /dev/null +++ b/Watcher/ViewModels/EditUserSettingsViewModel.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; + +namespace Watcher.ViewModels; + +public class EditUserSettingsViewModel +{ + [Required] + public string? Username { get; set; } + + [Required] + [DataType(DataType.Password)] + public string? NewPassword { get; set; } + + [Required] + [DataType(DataType.Password)] + [Compare("NewPassword", ErrorMessage = "Passwörter stimmen nicht überein.")] + public string? ConfirmPassword { get; set; } +} diff --git a/Watcher/ViewModels/EditUserViewModel.cs b/Watcher/ViewModels/EditUserViewModel.cs new file mode 100644 index 0000000..30e3fe4 --- /dev/null +++ b/Watcher/ViewModels/EditUserViewModel.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; + +namespace Watcher.ViewModels; + +public class EditUserViewModel +{ + [Required] + public string? Username { get; set; } + + [Required] + [DataType(DataType.Password)] + public string? NewPassword { get; set; } + + [Required] + [DataType(DataType.Password)] + [Compare("NewPassword", ErrorMessage = "Passwörter stimmen nicht überein.")] + public string? ConfirmPassword { get; set; } +} diff --git a/Watcher/ViewModels/LoginViewModel.cs b/Watcher/ViewModels/LoginViewModel.cs new file mode 100644 index 0000000..d29bbf4 --- /dev/null +++ b/Watcher/ViewModels/LoginViewModel.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; + +namespace Watcher.ViewModels; + +public class LoginViewModel +{ + [Required] + public string Username { get; set; } = string.Empty; + + [Required] + [DataType(DataType.Password)] + public string Password { get; set; } = string.Empty; + + public string? ReturnUrl { get; set; } +} diff --git a/Watcher/Views/Auth/EditUser.cshtml b/Watcher/Views/Auth/EditUser.cshtml new file mode 100644 index 0000000..e69de29 diff --git a/Watcher/Views/Auth/Info.cshtml b/Watcher/Views/Auth/Info.cshtml index 95f7267..7be6c50 100644 --- a/Watcher/Views/Auth/Info.cshtml +++ b/Watcher/Views/Auth/Info.cshtml @@ -1,86 +1,95 @@ @{ ViewData["Title"] = "Account Info"; - var pictureUrl = User.Claims.FirstOrDefault(c => c.Type == "picture")?.Value ?? "123"; + var pictureUrl = User.Claims.FirstOrDefault(c => c.Type == "picture")?.Value ?? ""; + var preferredUsername = User.Claims.FirstOrDefault(c => c.Type == "preferred_username")?.Value ?? "admin"; + var isAdmin = preferredUsername == "admin"; + var preferred_username = ViewBag.name; } -

Account Info

- -
- @if (!string.IsNullOrEmpty(pictureUrl)) - { - Profilbild - } - else - { -
- @(User.Identity?.Name?.Substring(0,1).ToUpper() ?? "?") +
+
+
+ @if (!string.IsNullOrEmpty(pictureUrl)) + { + Profilbild + } + else + { +
+ @(User.Identity?.Name?.Substring(0,1).ToUpper() ?? "?") +
+ } +

+ @(User.FindFirst("PreferredUsername")?.Value ?? "Unbekannter Nutzer") +

+
- } -

@(User.FindFirst("name")?.Value ?? "Unbekannter Nutzer")

- - - - - - - - - - - - - - - - - - - - - - - - - - + + +
Username@(@User.Claims.FirstOrDefault(c => c.Type == "preferred_username")?.Value ?? "Nicht verfügbar")
E-Mail@(@User.Claims.FirstOrDefault(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")?.Value ?? "Nicht verfügbar")
Benutzer-ID@(User.FindFirst("sub")?.Value ?? "Nicht verfügbar")
Login-Zeit@(User.FindFirst("iat") != null - ? DateTimeOffset.FromUnixTimeSeconds(long.Parse(User.FindFirst("iat").Value)).ToLocalTime().ToString() - : "Nicht verfügbar") -
Token läuft ab@(User.FindFirst("exp") != null - ? DateTimeOffset.FromUnixTimeSeconds(long.Parse(User.FindFirst("exp").Value)).ToLocalTime().ToString() - : "Nicht verfügbar") -
Rollen - @{ - var roles = User.FindAll("role").Select(r => r.Value); - if (!roles.Any()) - { - Keine Rollen + + + + + + + + + + + + + + + + + + + + + + + + + - - -
Username@preferredUsername
E-Mail@(ViewBag.Mail ?? "Nicht verfügbar")
Benutzer-ID@(ViewBag.Id ?? "Nicht verfügbar")
Login-Zeit + @(User.FindFirst("iat") != null + ? DateTimeOffset.FromUnixTimeSeconds(long.Parse(User.FindFirst("iat").Value)).ToLocalTime().ToString() + : "Nicht verfügbar") +
Token läuft ab + @(User.FindFirst("exp") != null + ? DateTimeOffset.FromUnixTimeSeconds(long.Parse(User.FindFirst("exp").Value)).ToLocalTime().ToString() + : "Nicht verfügbar") +
Rollen + @{ + var roles = User.FindAll("role").Select(r => r.Value); + if (!roles.Any()) + { + Keine Rollen + } + else + { +
    + @foreach (var role in roles) + { +
  • @role
  • + } +
+ } } - else - { -
    - @foreach (var role in roles) - { -
  • @role
  • - } -
- } - } -
- -
- -
+
+
+
+ +
+
+ +
+
+
- - -

Alle Claims

-
    -@foreach (var claim in User.Claims) -{ -
  • @claim.Type: @claim.Value
  • -} -
\ No newline at end of file diff --git a/Watcher/Views/Auth/Login.cshtml b/Watcher/Views/Auth/Login.cshtml index e09cffc..7147327 100644 --- a/Watcher/Views/Auth/Login.cshtml +++ b/Watcher/Views/Auth/Login.cshtml @@ -1,9 +1,87 @@ +@model Watcher.ViewModels.LoginViewModel @{ + Layout = "~/Views/Shared/_LoginLayout.cshtml"; ViewData["Title"] = "Login"; } -

Willkommen beim Watcher

+ + + diff --git a/Watcher/Views/Auth/UserSettings.cshtml b/Watcher/Views/Auth/UserSettings.cshtml new file mode 100644 index 0000000..d2c1bbd --- /dev/null +++ b/Watcher/Views/Auth/UserSettings.cshtml @@ -0,0 +1,130 @@ +@{ + ViewData["Title"] = "Settings"; + var pictureUrl = User.Claims.FirstOrDefault(c => c.Type == "picture")?.Value ?? ""; + var preferredUsername = User.Claims.FirstOrDefault(c => c.Type == "preferred_username")?.Value ?? "admin"; + var isLocalUser = ViewBag.IdentityProvider == "local"; + var DbEngine = ViewBag.DbProvider; +} + + + +
+ @if (isLocalUser) + { +
+

Benutzerdaten ändern

+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ } + else + { +
+ Benutzerdaten können nur für lokal angemeldete Nutzer geändert werden. +
+ } + + +
+

Systemeinformationen

+ +
+ +
Watcher Version: v0.1.0
+ +
+ +
Authentifizierungsmethode:
+

@(ViewBag.IdentityProvider ?? "nicht gefunden")

+ +
+ +
Datenbank-Engine:
+ @(DbEngine ?? "nicht gefunden") + + + @if (DbEngine == "Microsoft.EntityFrameworkCore.Sqlite") + { +
+
+ +
+ +
+ +
+
+ + } + else if (DbEngine == "Microsoft.EntityFrameworkCore.MySQL") + { +

MySQL Dump aktuell nicht möglich

+ } + + + @if (TempData["DumpMessage"] != null) + { +
+ @TempData["DumpMessage"] +
+ } + @if (TempData["DumpError"] != null) + { +
+ @TempData["DumpError"] +
+ } + +
+ +
+

Systemeinstellungen ändern

+ +
Anzeigeeinstellungen:
+ +
+ +
Benachrichtigungen:
+

Registrierte E-Mail Adresse: @(ViewBag.mail ?? "nicht gefunden")

+ +
+ +
...:
+ + + +
+
diff --git a/Watcher/Views/Database/ManageSqlDumps.cshtml b/Watcher/Views/Database/ManageSqlDumps.cshtml new file mode 100644 index 0000000..059aa61 --- /dev/null +++ b/Watcher/Views/Database/ManageSqlDumps.cshtml @@ -0,0 +1,54 @@ +@model List +@{ + ViewData["Title"] = "Datenbank-Dumps"; +} + +

Datenbank-Dumps

+ +@if (TempData["Success"] != null) +{ +
@TempData["Success"]
+} +@if (TempData["Error"] != null) +{ +
@TempData["Error"]
+} + + + + + + + + + + + + @foreach (var dump in Model) + { + + + + + + + } + +
DateinameGröße (KB)ErstelltAktionen
@dump.FileName@dump.SizeKb@dump.Created.ToString("dd.MM.yyyy HH:mm") + + Download + + +
+ +
+ +
+ +
+
diff --git a/Watcher/Views/Home/Index.cshtml b/Watcher/Views/Home/Index.cshtml index 627e7d3..8bd1f6b 100644 --- a/Watcher/Views/Home/Index.cshtml +++ b/Watcher/Views/Home/Index.cshtml @@ -3,34 +3,51 @@ ViewData["Title"] = "Dashboard"; } -

Dashboard

+

Dashboard

-
-
-

Server

-

🟢 Online: @Model.ActiveServers

-

🔴 Offline: @Model.OfflineServers

- → Zu den Servern -
+
+ @await Html.PartialAsync("_DashboardStats", Model) +
-
-

Container

-

🟢 Laufend: @Model.RunningContainers

-

🔴 Fehlerhaft: @Model.FailedContainers

- → Zu den Containern -
-
-

Uptime letzte 24h

-
- (Diagramm folgt hier) +
+
+
+

Uptime letzte 24h

+
+
+ (Diagramm folgt hier) +
-
-

Systeminfo

-

Benutzer: @User.FindFirst("preferred_username")?.Value

-

Letzter Login: @Model.LastLogin.ToString("g")

- → Account-Verwaltung +
+
+

Systeminfo

+

Benutzer: @User.FindFirst("preferred_username")?.Value

+

Letzter Login: @Model.LastLogin.ToString("g")

+
+ +@section Scripts { + +} diff --git a/Watcher/Views/Home/_DashboardStats.cshtml b/Watcher/Views/Home/_DashboardStats.cshtml new file mode 100644 index 0000000..a749114 --- /dev/null +++ b/Watcher/Views/Home/_DashboardStats.cshtml @@ -0,0 +1,17 @@ +@model Watcher.ViewModels.DashboardViewModel + +
+
+

Server

+

🟢 Online: @Model.ActiveServers

+

🔴 Offline: @Model.OfflineServers

+ → Zu den Servern +
+ +
+

Container

+

🟢 Laufend: @Model.RunningContainers

+

🔴 Fehlerhaft: @Model.FailedContainers

+ → Zu den Containern +
+
diff --git a/Watcher/Views/Server/AddServer.cshtml b/Watcher/Views/Server/AddServer.cshtml index 97471fb..5ef860f 100644 --- a/Watcher/Views/Server/AddServer.cshtml +++ b/Watcher/Views/Server/AddServer.cshtml @@ -3,38 +3,44 @@ ViewData["Title"] = "Neuen Server hinzufügen"; } -
-

Neuen Server hinzufügen

+
+
+

+ Neuen Server hinzufügen +

-
-
- - - -
+ +
+ + + +
-
- - - -
+
+ + + +
-
- - -
+
+ + +
-
- Abbrechen - -
-
+
+ + Abbrechen + + +
+ +
@section Scripts { diff --git a/Watcher/Views/Server/_ServerCard.cshtml b/Watcher/Views/Server/_ServerCard.cshtml new file mode 100644 index 0000000..22cf30c --- /dev/null +++ b/Watcher/Views/Server/_ServerCard.cshtml @@ -0,0 +1,55 @@ +@model IEnumerable + + +
+ @foreach (var s in Model) + { +
+
+

+ (#@s.Id) @s.Name +

+ + + @(s.IsOnline ? "Online" : "Offline") + +
+ +
+ +
+
IP: @s.IPAddress
+
Typ: @s.Type
+
Erstellt: + @s.CreatedAt.ToLocalTime().ToString("dd.MM.yyyy HH:mm")
+
Last-Seen: + @s.LastSeen.ToLocalTime().ToString("dd.MM.yyyy HH:mm")
+
+ + +
+ + +
+
+ + +
+ } +
diff --git a/Watcher/Views/Server/overview.cshtml b/Watcher/Views/Server/overview.cshtml index 6e7a32a..ffe8ae0 100644 --- a/Watcher/Views/Server/overview.cshtml +++ b/Watcher/Views/Server/overview.cshtml @@ -4,44 +4,37 @@ } -
- @foreach (var s in Model.Servers) - { -
-
-
-

(#@s.Id) @s.Name

-
- - @(s.IsOnline ? "Online" : "Offline") - -
- -
-
IP: @s.IPAddress
-
Typ: @s.Type
-
Status: @((s.IsOnline) ? "Online" : "Offline")
-
Erstellt: @s.CreatedAt.ToLocalTime().ToString("dd.MM.yyyy HH:mm")
-
Last-Seen: @(s.LastSeen.ToLocalTime().ToString("dd.MM.yyyy HH:mm") ?? "Never") -
-
- -
- Bearbeiten - -
- -
-
-
- } +
+ @await Html.PartialAsync("_ServerCard", Model.Servers)
+ +@section Scripts { + +} diff --git a/Watcher/Views/Shared/_Layout.cshtml b/Watcher/Views/Shared/_Layout.cshtml index aaac9d9..985d7e9 100644 --- a/Watcher/Views/Shared/_Layout.cshtml +++ b/Watcher/Views/Shared/_Layout.cshtml @@ -14,6 +14,7 @@ @ViewData["Title"] - Watcher + @@ -59,20 +60,27 @@