diff --git a/MoonlightServers.ApiServer/Database/Entities/Allocation.cs b/MoonlightServers.ApiServer/Database/Entities/Allocation.cs new file mode 100644 index 0000000..03f4f21 --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Entities/Allocation.cs @@ -0,0 +1,12 @@ +namespace MoonlightServers.ApiServer.Database.Entities; + +public class Allocation +{ + public int Id { get; set; } + + public string IpAddress { get; set; } = "0.0.0.0"; + public int Port { get; set; } + + public Server? Server { get; set; } + public Node Node { get; set; } +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Database/Entities/Backup.cs b/MoonlightServers.ApiServer/Database/Entities/Backup.cs new file mode 100644 index 0000000..de0b97e --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Entities/Backup.cs @@ -0,0 +1,18 @@ +using MoonlightServers.Shared.Enums; + +namespace MoonlightServers.ApiServer.Database.Entities; + +public class Backup +{ + public int Id { get; set; } + + public string Name { get; set; } + public BackupState State { get; set; } + + public long Size { get; set; } + + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + public DateTime FinishedAt { get; set; } = DateTime.UtcNow; + + public Server Server { get; set; } +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Database/Entities/Network.cs b/MoonlightServers.ApiServer/Database/Entities/Network.cs new file mode 100644 index 0000000..404eb77 --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Entities/Network.cs @@ -0,0 +1,11 @@ +namespace MoonlightServers.ApiServer.Database.Entities; + +public class Network +{ + public int Id { get; set; } + + public string Name { get; set; } + + public Node Node { get; set; } + public List Servers { get; set; } = new(); +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Database/Entities/Node.cs b/MoonlightServers.ApiServer/Database/Entities/Node.cs new file mode 100644 index 0000000..6be8775 --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Entities/Node.cs @@ -0,0 +1,16 @@ +namespace MoonlightServers.ApiServer.Database.Entities; + +public class Node +{ + public int Id { get; set; } + + public string Name { get; set; } + + public string Fqdn { get; set; } + public int ApiPort { get; set; } + public string Token { get; set; } + public bool SslEnabled { get; set; } + + public List Allocations { get; set; } = new(); + public List Servers { get; set; } = new(); +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Database/Entities/Server.cs b/MoonlightServers.ApiServer/Database/Entities/Server.cs new file mode 100644 index 0000000..eacec4c --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Entities/Server.cs @@ -0,0 +1,26 @@ +namespace MoonlightServers.ApiServer.Database.Entities; + +public class Server +{ + public int Id { get; set; } + + public string Name { get; set; } + + public int Cpu { get; set; } + public int Memory { get; set; } + public int Disk { get; set; } + + public string? OverrideStartupCommand { get; set; } = null; + public string? OverrideDockerImage { get; set; } = null; + + public bool VirtualDiskEnabled { get; set; } = false; + + public Star Star { get; set; } + public int DockerImageIndex { get; set; } = 0; + + public Node Node { get; set; } + public Network? Network { get; set; } + public List Allocations { get; set; } = new(); + public List Variables { get; set; } = new(); + public List Backups { get; set; } = new(); +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Database/Entities/ServerVariable.cs b/MoonlightServers.ApiServer/Database/Entities/ServerVariable.cs new file mode 100644 index 0000000..1690c32 --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Entities/ServerVariable.cs @@ -0,0 +1,11 @@ +namespace MoonlightServers.ApiServer.Database.Entities; + +public class ServerVariable +{ + public int Id { get; set; } + + public string Key { get; set; } + public string Value { get; set; } + + public Server Server { get; set; } +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Database/Entities/Star.cs b/MoonlightServers.ApiServer/Database/Entities/Star.cs new file mode 100644 index 0000000..a56f2f2 --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Entities/Star.cs @@ -0,0 +1,31 @@ +namespace MoonlightServers.ApiServer.Database.Entities; + +public class Star +{ + public int Id { get; set; } + + public string Name { get; set; } + public string Author { get; set; } + + public string? DonationUrl { get; set; } + public string? UpdateUrl { get; set; } + + public string StartupCommand { get; set; } + public string StopCommand { get; set; } + public string OnlineDetection { get; set; } + + public string InstallShell { get; set; } + public string InstallDockerImage { get; set; } + public string InstallScript { get; set; } + public int RequiredAllocations { get; set; } + + public string ParseConfiguration { get; set; } + + public int DefaultDockerImageIndex { get; set; } + public bool AllowDockerImageChanging { get; set; } + + public List Variables { get; set; } = new(); + public List DockerImages { get; set; } = new(); + + public StarFolder? Folder { get; set; } +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Database/Entities/StarDockerImage.cs b/MoonlightServers.ApiServer/Database/Entities/StarDockerImage.cs new file mode 100644 index 0000000..00d89b0 --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Entities/StarDockerImage.cs @@ -0,0 +1,11 @@ +namespace MoonlightServers.ApiServer.Database.Entities; + +public class StarDockerImage +{ + public int Id { get; set; } + + public string Identifier { get; set; } + public string DisplayName { get; set; } + + public bool AutoPulling { get; set; } = true; +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Database/Entities/StarFolder.cs b/MoonlightServers.ApiServer/Database/Entities/StarFolder.cs new file mode 100644 index 0000000..cc6a34d --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Entities/StarFolder.cs @@ -0,0 +1,10 @@ +namespace MoonlightServers.ApiServer.Database.Entities; + +public class StarFolder +{ + public int Id { get; set; } + + public string Name { get; set; } + + public List Stars { get; set; } = new(); +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Database/Entities/StarVariable.cs b/MoonlightServers.ApiServer/Database/Entities/StarVariable.cs new file mode 100644 index 0000000..b4f7fb5 --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Entities/StarVariable.cs @@ -0,0 +1,20 @@ +using MoonlightServers.Shared.Enums; + +namespace MoonlightServers.ApiServer.Database.Entities; + +public class StarVariable +{ + public int Id { get; set; } + + public string Key { get; set; } + public string DefaultValue { get; set; } + + public string DisplayName { get; set; } + public string Description { get; set; } + + public bool AllowViewing { get; set; } = false; + public bool AllowEditing { get; set; } = false; + + public string? Filter { get; set; } + public StarVariableType Type { get; set; } = StarVariableType.Text; +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Database/Migrations/20240830074359_AddedServerEntities.Designer.cs b/MoonlightServers.ApiServer/Database/Migrations/20240830074359_AddedServerEntities.Designer.cs new file mode 100644 index 0000000..18ef4cb --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Migrations/20240830074359_AddedServerEntities.Designer.cs @@ -0,0 +1,519 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MoonlightServers.ApiServer.Database; + +#nullable disable + +namespace MoonlightServers.ApiServer.Database.Migrations +{ + [DbContext(typeof(ServersContext))] + [Migration("20240830074359_AddedServerEntities")] + partial class AddedServerEntities + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("Servers") + .HasAnnotation("ProductVersion", "8.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Allocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NodeId") + .HasColumnType("int"); + + b.Property("Port") + .HasColumnType("int"); + + b.Property("ServerId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NodeId"); + + b.HasIndex("ServerId"); + + b.ToTable("Allocations", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Backup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FinishedAt") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ServerId") + .HasColumnType("int"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.Property("State") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("Backups", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Network", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NodeId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NodeId"); + + b.ToTable("Networks", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Node", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ApiPort") + .HasColumnType("int"); + + b.Property("Fqdn") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("SslEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Nodes", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Cpu") + .HasColumnType("int"); + + b.Property("Disk") + .HasColumnType("int"); + + b.Property("DockerImageIndex") + .HasColumnType("int"); + + b.Property("Memory") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NetworkId") + .HasColumnType("int"); + + b.Property("NodeId") + .HasColumnType("int"); + + b.Property("OverrideDockerImage") + .HasColumnType("longtext"); + + b.Property("OverrideStartupCommand") + .HasColumnType("longtext"); + + b.Property("StarId") + .HasColumnType("int"); + + b.Property("VirtualDiskEnabled") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("NetworkId"); + + b.HasIndex("NodeId"); + + b.HasIndex("StarId"); + + b.ToTable("Servers", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.ServerVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Key") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ServerId") + .HasColumnType("int"); + + b.Property("Value") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("ServerVariables", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Star", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowDockerImageChanging") + .HasColumnType("tinyint(1)"); + + b.Property("Author") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DefaultDockerImageIndex") + .HasColumnType("int"); + + b.Property("DonationUrl") + .HasColumnType("longtext"); + + b.Property("FolderId") + .HasColumnType("int"); + + b.Property("InstallDockerImage") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("InstallScript") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("InstallShell") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("OnlineDetection") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ParseConfiguration") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RequiredAllocations") + .HasColumnType("int"); + + b.Property("StartupCommand") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StopCommand") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdateUrl") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FolderId"); + + b.ToTable("Stars", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarDockerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AutoPulling") + .HasColumnType("tinyint(1)"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Identifier") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StarId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StarId"); + + b.ToTable("StarDockerImages", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarFolder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("StarFolders", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowEditing") + .HasColumnType("tinyint(1)"); + + b.Property("AllowViewing") + .HasColumnType("tinyint(1)"); + + b.Property("DefaultValue") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Filter") + .HasColumnType("longtext"); + + b.Property("Key") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StarId") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StarId"); + + b.ToTable("StarVariables", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Allocation", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Node", "Node") + .WithMany("Allocations") + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Server", "Server") + .WithMany("Allocations") + .HasForeignKey("ServerId"); + + b.Navigation("Node"); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Backup", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Server", "Server") + .WithMany("Backups") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Network", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Node", "Node") + .WithMany() + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Node"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Server", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Network", "Network") + .WithMany("Servers") + .HasForeignKey("NetworkId"); + + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Node", "Node") + .WithMany("Servers") + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Star", "Star") + .WithMany() + .HasForeignKey("StarId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Network"); + + b.Navigation("Node"); + + b.Navigation("Star"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.ServerVariable", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Server", "Server") + .WithMany("Variables") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Star", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.StarFolder", "Folder") + .WithMany("Stars") + .HasForeignKey("FolderId"); + + b.Navigation("Folder"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarDockerImage", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Star", null) + .WithMany("DockerImages") + .HasForeignKey("StarId"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarVariable", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Star", null) + .WithMany("Variables") + .HasForeignKey("StarId"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Network", b => + { + b.Navigation("Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Node", b => + { + b.Navigation("Allocations"); + + b.Navigation("Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Server", b => + { + b.Navigation("Allocations"); + + b.Navigation("Backups"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Star", b => + { + b.Navigation("DockerImages"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarFolder", b => + { + b.Navigation("Stars"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MoonlightServers.ApiServer/Database/Migrations/20240830074359_AddedServerEntities.cs b/MoonlightServers.ApiServer/Database/Migrations/20240830074359_AddedServerEntities.cs new file mode 100644 index 0000000..98f385e --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Migrations/20240830074359_AddedServerEntities.cs @@ -0,0 +1,434 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MoonlightServers.ApiServer.Database.Migrations +{ + /// + public partial class AddedServerEntities : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "Servers"); + + migrationBuilder.AlterDatabase() + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Nodes", + schema: "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"), + Fqdn = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ApiPort = table.Column(type: "int", nullable: false), + Token = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + SslEnabled = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Nodes", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "StarFolders", + schema: "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") + }, + constraints: table => + { + table.PrimaryKey("PK_StarFolders", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Networks", + schema: "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"), + NodeId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Networks", x => x.Id); + table.ForeignKey( + name: "FK_Networks_Nodes_NodeId", + column: x => x.NodeId, + principalSchema: "Servers", + principalTable: "Nodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Stars", + schema: "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"), + Author = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + DonationUrl = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + UpdateUrl = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + StartupCommand = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + StopCommand = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + OnlineDetection = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + InstallShell = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + InstallDockerImage = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + InstallScript = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + RequiredAllocations = table.Column(type: "int", nullable: false), + ParseConfiguration = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + DefaultDockerImageIndex = table.Column(type: "int", nullable: false), + AllowDockerImageChanging = table.Column(type: "tinyint(1)", nullable: false), + FolderId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Stars", x => x.Id); + table.ForeignKey( + name: "FK_Stars_StarFolders_FolderId", + column: x => x.FolderId, + principalSchema: "Servers", + principalTable: "StarFolders", + principalColumn: "Id"); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Servers", + schema: "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"), + Cpu = table.Column(type: "int", nullable: false), + Memory = table.Column(type: "int", nullable: false), + Disk = table.Column(type: "int", nullable: false), + OverrideStartupCommand = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + OverrideDockerImage = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + VirtualDiskEnabled = table.Column(type: "tinyint(1)", nullable: false), + StarId = table.Column(type: "int", nullable: false), + DockerImageIndex = table.Column(type: "int", nullable: false), + NodeId = table.Column(type: "int", nullable: false), + NetworkId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Servers", x => x.Id); + table.ForeignKey( + name: "FK_Servers_Networks_NetworkId", + column: x => x.NetworkId, + principalSchema: "Servers", + principalTable: "Networks", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Servers_Nodes_NodeId", + column: x => x.NodeId, + principalSchema: "Servers", + principalTable: "Nodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Servers_Stars_StarId", + column: x => x.StarId, + principalSchema: "Servers", + principalTable: "Stars", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "StarDockerImages", + schema: "Servers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Identifier = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + DisplayName = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + AutoPulling = table.Column(type: "tinyint(1)", nullable: false), + StarId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_StarDockerImages", x => x.Id); + table.ForeignKey( + name: "FK_StarDockerImages_Stars_StarId", + column: x => x.StarId, + principalSchema: "Servers", + principalTable: "Stars", + principalColumn: "Id"); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "StarVariables", + schema: "Servers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Key = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + DefaultValue = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + DisplayName = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Description = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + AllowViewing = table.Column(type: "tinyint(1)", nullable: false), + AllowEditing = table.Column(type: "tinyint(1)", nullable: false), + Filter = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Type = table.Column(type: "int", nullable: false), + StarId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_StarVariables", x => x.Id); + table.ForeignKey( + name: "FK_StarVariables_Stars_StarId", + column: x => x.StarId, + principalSchema: "Servers", + principalTable: "Stars", + principalColumn: "Id"); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Allocations", + schema: "Servers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + IpAddress = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Port = table.Column(type: "int", nullable: false), + ServerId = table.Column(type: "int", nullable: true), + NodeId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Allocations", x => x.Id); + table.ForeignKey( + name: "FK_Allocations_Nodes_NodeId", + column: x => x.NodeId, + principalSchema: "Servers", + principalTable: "Nodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Allocations_Servers_ServerId", + column: x => x.ServerId, + principalSchema: "Servers", + principalTable: "Servers", + principalColumn: "Id"); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Backups", + schema: "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"), + State = table.Column(type: "int", nullable: false), + Size = table.Column(type: "bigint", nullable: false), + CreatedAt = table.Column(type: "datetime(6)", nullable: false), + FinishedAt = table.Column(type: "datetime(6)", nullable: false), + ServerId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Backups", x => x.Id); + table.ForeignKey( + name: "FK_Backups_Servers_ServerId", + column: x => x.ServerId, + principalSchema: "Servers", + principalTable: "Servers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "ServerVariables", + schema: "Servers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Key = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Value = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ServerId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ServerVariables", x => x.Id); + table.ForeignKey( + name: "FK_ServerVariables_Servers_ServerId", + column: x => x.ServerId, + principalSchema: "Servers", + principalTable: "Servers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_Allocations_NodeId", + schema: "Servers", + table: "Allocations", + column: "NodeId"); + + migrationBuilder.CreateIndex( + name: "IX_Allocations_ServerId", + schema: "Servers", + table: "Allocations", + column: "ServerId"); + + migrationBuilder.CreateIndex( + name: "IX_Backups_ServerId", + schema: "Servers", + table: "Backups", + column: "ServerId"); + + migrationBuilder.CreateIndex( + name: "IX_Networks_NodeId", + schema: "Servers", + table: "Networks", + column: "NodeId"); + + migrationBuilder.CreateIndex( + name: "IX_Servers_NetworkId", + schema: "Servers", + table: "Servers", + column: "NetworkId"); + + migrationBuilder.CreateIndex( + name: "IX_Servers_NodeId", + schema: "Servers", + table: "Servers", + column: "NodeId"); + + migrationBuilder.CreateIndex( + name: "IX_Servers_StarId", + schema: "Servers", + table: "Servers", + column: "StarId"); + + migrationBuilder.CreateIndex( + name: "IX_ServerVariables_ServerId", + schema: "Servers", + table: "ServerVariables", + column: "ServerId"); + + migrationBuilder.CreateIndex( + name: "IX_StarDockerImages_StarId", + schema: "Servers", + table: "StarDockerImages", + column: "StarId"); + + migrationBuilder.CreateIndex( + name: "IX_Stars_FolderId", + schema: "Servers", + table: "Stars", + column: "FolderId"); + + migrationBuilder.CreateIndex( + name: "IX_StarVariables_StarId", + schema: "Servers", + table: "StarVariables", + column: "StarId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Allocations", + schema: "Servers"); + + migrationBuilder.DropTable( + name: "Backups", + schema: "Servers"); + + migrationBuilder.DropTable( + name: "ServerVariables", + schema: "Servers"); + + migrationBuilder.DropTable( + name: "StarDockerImages", + schema: "Servers"); + + migrationBuilder.DropTable( + name: "StarVariables", + schema: "Servers"); + + migrationBuilder.DropTable( + name: "Servers", + schema: "Servers"); + + migrationBuilder.DropTable( + name: "Networks", + schema: "Servers"); + + migrationBuilder.DropTable( + name: "Stars", + schema: "Servers"); + + migrationBuilder.DropTable( + name: "Nodes", + schema: "Servers"); + + migrationBuilder.DropTable( + name: "StarFolders", + schema: "Servers"); + } + } +} diff --git a/MoonlightServers.ApiServer/Database/Migrations/ServersContextModelSnapshot.cs b/MoonlightServers.ApiServer/Database/Migrations/ServersContextModelSnapshot.cs new file mode 100644 index 0000000..8fd0248 --- /dev/null +++ b/MoonlightServers.ApiServer/Database/Migrations/ServersContextModelSnapshot.cs @@ -0,0 +1,516 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MoonlightServers.ApiServer.Database; + +#nullable disable + +namespace MoonlightServers.ApiServer.Database.Migrations +{ + [DbContext(typeof(ServersContext))] + partial class ServersContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("Servers") + .HasAnnotation("ProductVersion", "8.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Allocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NodeId") + .HasColumnType("int"); + + b.Property("Port") + .HasColumnType("int"); + + b.Property("ServerId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NodeId"); + + b.HasIndex("ServerId"); + + b.ToTable("Allocations", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Backup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("FinishedAt") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ServerId") + .HasColumnType("int"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.Property("State") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("Backups", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Network", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NodeId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NodeId"); + + b.ToTable("Networks", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Node", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ApiPort") + .HasColumnType("int"); + + b.Property("Fqdn") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("SslEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Nodes", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Cpu") + .HasColumnType("int"); + + b.Property("Disk") + .HasColumnType("int"); + + b.Property("DockerImageIndex") + .HasColumnType("int"); + + b.Property("Memory") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NetworkId") + .HasColumnType("int"); + + b.Property("NodeId") + .HasColumnType("int"); + + b.Property("OverrideDockerImage") + .HasColumnType("longtext"); + + b.Property("OverrideStartupCommand") + .HasColumnType("longtext"); + + b.Property("StarId") + .HasColumnType("int"); + + b.Property("VirtualDiskEnabled") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("NetworkId"); + + b.HasIndex("NodeId"); + + b.HasIndex("StarId"); + + b.ToTable("Servers", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.ServerVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Key") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ServerId") + .HasColumnType("int"); + + b.Property("Value") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("ServerVariables", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Star", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowDockerImageChanging") + .HasColumnType("tinyint(1)"); + + b.Property("Author") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DefaultDockerImageIndex") + .HasColumnType("int"); + + b.Property("DonationUrl") + .HasColumnType("longtext"); + + b.Property("FolderId") + .HasColumnType("int"); + + b.Property("InstallDockerImage") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("InstallScript") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("InstallShell") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("OnlineDetection") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ParseConfiguration") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RequiredAllocations") + .HasColumnType("int"); + + b.Property("StartupCommand") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StopCommand") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdateUrl") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FolderId"); + + b.ToTable("Stars", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarDockerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AutoPulling") + .HasColumnType("tinyint(1)"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Identifier") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StarId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StarId"); + + b.ToTable("StarDockerImages", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarFolder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("StarFolders", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowEditing") + .HasColumnType("tinyint(1)"); + + b.Property("AllowViewing") + .HasColumnType("tinyint(1)"); + + b.Property("DefaultValue") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Filter") + .HasColumnType("longtext"); + + b.Property("Key") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("StarId") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StarId"); + + b.ToTable("StarVariables", "Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Allocation", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Node", "Node") + .WithMany("Allocations") + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Server", "Server") + .WithMany("Allocations") + .HasForeignKey("ServerId"); + + b.Navigation("Node"); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Backup", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Server", "Server") + .WithMany("Backups") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Network", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Node", "Node") + .WithMany() + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Node"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Server", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Network", "Network") + .WithMany("Servers") + .HasForeignKey("NetworkId"); + + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Node", "Node") + .WithMany("Servers") + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Star", "Star") + .WithMany() + .HasForeignKey("StarId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Network"); + + b.Navigation("Node"); + + b.Navigation("Star"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.ServerVariable", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Server", "Server") + .WithMany("Variables") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Star", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.StarFolder", "Folder") + .WithMany("Stars") + .HasForeignKey("FolderId"); + + b.Navigation("Folder"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarDockerImage", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Star", null) + .WithMany("DockerImages") + .HasForeignKey("StarId"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarVariable", b => + { + b.HasOne("MoonlightServers.ApiServer.Database.Entities.Star", null) + .WithMany("Variables") + .HasForeignKey("StarId"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Network", b => + { + b.Navigation("Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Node", b => + { + b.Navigation("Allocations"); + + b.Navigation("Servers"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Server", b => + { + b.Navigation("Allocations"); + + b.Navigation("Backups"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.Star", b => + { + b.Navigation("DockerImages"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("MoonlightServers.ApiServer.Database.Entities.StarFolder", b => + { + b.Navigation("Stars"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MoonlightServers.ApiServer/Database/ServersContext.cs b/MoonlightServers.ApiServer/Database/ServersContext.cs index 5461244..86c4877 100644 --- a/MoonlightServers.ApiServer/Database/ServersContext.cs +++ b/MoonlightServers.ApiServer/Database/ServersContext.cs @@ -1,8 +1,21 @@ +using Microsoft.EntityFrameworkCore; using Moonlight.ApiServer.App.Helpers.Database; +using MoonlightServers.ApiServer.Database.Entities; namespace MoonlightServers.ApiServer.Database; public class ServersContext : DatabaseContext { public override string Prefix => "Servers"; + + public DbSet Allocations { get; set; } + public DbSet Backups { get; set; } + public DbSet Networks { get; set; } + public DbSet Nodes { get; set; } + public DbSet Servers { get; set; } + public DbSet ServerVariables { get; set; } + public DbSet Stars { get; set; } + public DbSet StarDockerImages { get; set; } + public DbSet StarFolders { get; set; } + public DbSet StarVariables { get; set; } } \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Http/Controllers/Admin/NodesController.cs b/MoonlightServers.ApiServer/Http/Controllers/Admin/NodesController.cs new file mode 100644 index 0000000..68bb362 --- /dev/null +++ b/MoonlightServers.ApiServer/Http/Controllers/Admin/NodesController.cs @@ -0,0 +1,84 @@ +using System.Text.RegularExpressions; +using Microsoft.AspNetCore.Mvc; +using MoonCore.Extended.Abstractions; +using MoonCore.Helpers; +using Moonlight.ApiServer.App.Attributes; +using Moonlight.ApiServer.App.Exceptions; +using Moonlight.ApiServer.App.Helpers; +using MoonlightServers.ApiServer.Database.Entities; +using MoonlightServers.Shared.Http.Requests.Admin.Nodes; +using MoonlightServers.Shared.Http.Responses.Admin.Nodes; + +namespace MoonlightServers.ApiServer.Http.Controllers.Admin; + +[ApiController] +[Route("admin/servers/nodes")] +public class NodesController : BaseCrudController +{ + private DatabaseRepository NodeRepository; + private DatabaseRepository AllocationRepository; + + public NodesController(DatabaseRepository itemRepository, DatabaseRepository allocationRepository) : base(itemRepository) + { + PermissionPrefix = "admin.servers.nodes"; + + NodeRepository = itemRepository; + AllocationRepository = allocationRepository; + } + + [HttpPost] + [RequirePermission("admin.servers.nodes.create")] + public override async Task> Create(CreateNodeRequest request) + { + ValidateFqdn(request.Fqdn, request.SslEnabled); + + var node = Mapper.Map(request); + node.Token = Formatter.GenerateString(32); + + var finalNode = NodeRepository.Add(node); + + return Ok(Mapper.Map(finalNode)); + } + + [HttpPatch("{id}")] + [RequirePermission("admin.servers.nodes.update")] + public override async Task> Update(int id, UpdateNodeRequest request) + { + ValidateFqdn(request.Fqdn, request.SslEnabled); + + var item = LoadItemById(id); + + item = Mapper.Map(item, request); + + NodeRepository.Update(item); + + return Ok(Mapper.Map(item)); + } + + private void ValidateFqdn(string fqdn, bool ssl) + { + if (ssl) + { + // Is it a valid domain? + if (Regex.IsMatch(fqdn, "^(?!-)(?:[a-zA-Z\\d-]{0,62}[a-zA-Z\\d]\\.)+(?:[a-zA-Z]{2,})$")) + return; + + throw new ApiException("The fqdn needs to be a valid domain. If you want to use an ip address as the fqdn, disable ssl for this node", statusCode: 400); + } + else + { + // Is it a valid domain? + if (Regex.IsMatch(fqdn, "^(?!-)(?:[a-zA-Z\\d-]{0,62}[a-zA-Z\\d]\\.)+(?:[a-zA-Z]{2,})$")) + return; + + // Is it a valid ip? + if (Regex.IsMatch(fqdn, "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")) + return; + + throw new ApiException("The fqdn needs to be either a domain or an ip", statusCode: 400); + } + } + + // Allocations + +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/MoonlightServers.ApiServer.csproj b/MoonlightServers.ApiServer/MoonlightServers.ApiServer.csproj index 4f404eb..676dbbb 100644 --- a/MoonlightServers.ApiServer/MoonlightServers.ApiServer.csproj +++ b/MoonlightServers.ApiServer/MoonlightServers.ApiServer.csproj @@ -37,10 +37,9 @@ - + - diff --git a/MoonlightServers.Client/MoonlightServers.Client.csproj b/MoonlightServers.Client/MoonlightServers.Client.csproj index 6e6c36a..11f94f9 100644 --- a/MoonlightServers.Client/MoonlightServers.Client.csproj +++ b/MoonlightServers.Client/MoonlightServers.Client.csproj @@ -36,7 +36,6 @@ - diff --git a/MoonlightServers.Client/UI/Views/Admin/Index.razor b/MoonlightServers.Client/UI/Views/Admin/Index.razor new file mode 100644 index 0000000..ae0fca9 --- /dev/null +++ b/MoonlightServers.Client/UI/Views/Admin/Index.razor @@ -0,0 +1,5 @@ +@page "/admin/servers" + +@attribute [RequirePermission("admin.servers.get")] + + \ No newline at end of file diff --git a/MoonlightServers.Client/UI/Views/Admin/Nodes.razor b/MoonlightServers.Client/UI/Views/Admin/Nodes.razor new file mode 100644 index 0000000..775f44e --- /dev/null +++ b/MoonlightServers.Client/UI/Views/Admin/Nodes.razor @@ -0,0 +1,87 @@ +@page "/admin/servers/nodes" + +@using Moonlight.Client.App.Models.Crud +@using Moonlight.Shared.Http.Resources +@using MoonlightServers.Shared.Http.Requests.Admin.Nodes +@using MoonlightServers.Shared.Http.Responses.Admin.Nodes + +@inject HttpApiClient HttpApiClient + +@attribute [RequirePermission("admin.servers.nodes.get")] + + + +
+ + + + + + + +
+ +@code +{ + private void OnConfigure(CrudOptions options) + { + options.Loader = async (page, pageSize) => + await HttpApiClient.GetJson>($"admin/servers/nodes?page={page}&pageSize={pageSize}"); + + options.CreateFunction = async request => await HttpApiClient.Post("admin/servers/nodes", request); + options.UpdateFunction = async (request, item) => await HttpApiClient.Patch($"admin/servers/nodes/{item.Id}", request); + options.DeleteFunction = async item => await HttpApiClient.Delete($"admin/servers/nodes/{item.Id}"); + + options.ShowCreateAsModal = false; + options.ShowUpdateAsModal = false; + + options.OnConfigureCreate = option => + { + option + .DefaultPage + .DefaultSection + .AddProperty(x => x.Name); + + option + .DefaultPage + .DefaultSection + .AddProperty(x => x.Fqdn); + + option + .DefaultPage + .DefaultSection + .AddProperty(x => x.ApiPort); + + option + .WithPage("Security") + .DefaultSection + .AddProperty(x => x.SslEnabled); + }; + + options.OnConfigureUpdate = (option, item) => + { + option + .DefaultPage + .DefaultSection + .AddProperty(x => x.Name); + + option + .DefaultPage + .DefaultSection + .AddProperty(x => x.Fqdn); + + option + .DefaultPage + .DefaultSection + .AddProperty(x => x.ApiPort); + + option + .DefaultPage + .DefaultSection + .AddProperty(x => x.SslEnabled); + }; + } +} diff --git a/MoonlightServers.Shared/Enums/BackupState.cs b/MoonlightServers.Shared/Enums/BackupState.cs new file mode 100644 index 0000000..4b708ed --- /dev/null +++ b/MoonlightServers.Shared/Enums/BackupState.cs @@ -0,0 +1,8 @@ +namespace MoonlightServers.Shared.Enums; + +public enum BackupState +{ + Creating = 0, + Failed = 1, + Created = 2 +} \ No newline at end of file diff --git a/MoonlightServers.Shared/Enums/StarVariableType.cs b/MoonlightServers.Shared/Enums/StarVariableType.cs new file mode 100644 index 0000000..638148e --- /dev/null +++ b/MoonlightServers.Shared/Enums/StarVariableType.cs @@ -0,0 +1,9 @@ +namespace MoonlightServers.Shared.Enums; + +public enum StarVariableType +{ + Text = 0, + Number = 1, + Toggle = 2, + Select = 3 +} \ No newline at end of file diff --git a/MoonlightServers.Shared/Http/Requests/Admin/Nodes/CreateNodeRequest.cs b/MoonlightServers.Shared/Http/Requests/Admin/Nodes/CreateNodeRequest.cs new file mode 100644 index 0000000..38a0242 --- /dev/null +++ b/MoonlightServers.Shared/Http/Requests/Admin/Nodes/CreateNodeRequest.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; + +namespace MoonlightServers.Shared.Http.Requests.Admin.Nodes; + +public class CreateNodeRequest +{ + [Required(ErrorMessage = "You need to provide a name")] + public string Name { get; set; } + + [Required(ErrorMessage = "You need to provide a fqdn")] + public string Fqdn { get; set; } + + [Range(1, 65535, ErrorMessage = "You need to provide a valid port")] + public int ApiPort { get; set; } = 8080; + + public bool SslEnabled { get; set; } = false; +} \ No newline at end of file diff --git a/MoonlightServers.Shared/Http/Requests/Admin/Nodes/UpdateNodeRequest.cs b/MoonlightServers.Shared/Http/Requests/Admin/Nodes/UpdateNodeRequest.cs new file mode 100644 index 0000000..7c6acd7 --- /dev/null +++ b/MoonlightServers.Shared/Http/Requests/Admin/Nodes/UpdateNodeRequest.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; + +namespace MoonlightServers.Shared.Http.Requests.Admin.Nodes; + +public class UpdateNodeRequest +{ + [Required(ErrorMessage = "You need to provide a name")] + public string Name { get; set; } + + [Required(ErrorMessage = "You need to provide a fqdn")] + public string Fqdn { get; set; } + + [Range(1, 65535, ErrorMessage = "You need to provide a valid port")] + public int ApiPort { get; set; } = 8080; + + public bool SslEnabled { get; set; } = false; +} \ No newline at end of file diff --git a/MoonlightServers.Shared/Http/Responses/Admin/Nodes/DetailNodeResponse.cs b/MoonlightServers.Shared/Http/Responses/Admin/Nodes/DetailNodeResponse.cs new file mode 100644 index 0000000..166c322 --- /dev/null +++ b/MoonlightServers.Shared/Http/Responses/Admin/Nodes/DetailNodeResponse.cs @@ -0,0 +1,11 @@ +namespace MoonlightServers.Shared.Http.Responses.Admin.Nodes; + +public class DetailNodeResponse +{ + public int Id { get; set; } + + public string Name { get; set; } + public string Fqdn { get; set; } + public int ApiPort { get; set; } + public bool SslEnabled { get; set; } +} \ No newline at end of file diff --git a/MoonlightServers.Shared/MoonlightServers.Shared.csproj b/MoonlightServers.Shared/MoonlightServers.Shared.csproj index ae3d750..d8a2b4e 100644 --- a/MoonlightServers.Shared/MoonlightServers.Shared.csproj +++ b/MoonlightServers.Shared/MoonlightServers.Shared.csproj @@ -7,8 +7,6 @@ - -