Merge pull request #1303 from tgstation/1300-Invisabru

Adds option to change DreamDaemon visibility
This commit is contained in:
Jordan Brown
2021-08-25 19:40:46 -04:00
committed by GitHub
31 changed files with 4053 additions and 35 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
<PropertyGroup>
<TgsCoreVersion>4.14.0</TgsCoreVersion>
<TgsConfigVersion>4.0.0</TgsConfigVersion>
<TgsApiVersion>9.1.0</TgsApiVersion>
<TgsApiVersion>9.2.0</TgsApiVersion>
<TgsApiLibraryVersion>9.1.0</TgsApiLibraryVersion>
<TgsClientVersion>10.1.0</TgsClientVersion>
<TgsDmapiVersion>6.0.4</TgsDmapiVersion>
@@ -0,0 +1,23 @@
namespace Tgstation.Server.Api.Models
{
/// <summary>
/// The visibility setting for DreamDaemon.
/// </summary>
public enum DreamDaemonVisibility
{
/// <summary>
/// Public DreamDaemon visibility.
/// </summary>
Public,
/// <summary>
/// Private DreamDaemon visibility.
/// </summary>
Private,
/// <summary>
/// Invisible DreamDaemon visibility.
/// </summary>
Invisible,
}
}
@@ -15,6 +15,14 @@ namespace Tgstation.Server.Api.Models.Internal
[ResponseOptions]
public bool? AllowWebClient { get; set; }
/// <summary>
/// The <see cref="DreamDaemonVisibility"/> level of DreamDaemon.
/// </summary>
[Required]
[ResponseOptions]
[EnumDataType(typeof(DreamDaemonVisibility))]
public DreamDaemonVisibility? Visibility { get; set; }
/// <summary>
/// The <see cref="DreamDaemonSecurity"/> level of DreamDaemon.
/// </summary>
@@ -70,6 +78,7 @@ namespace Tgstation.Server.Api.Models.Internal
public bool CanApplyWithoutReboot(DreamDaemonLaunchParameters otherParameters) =>
AllowWebClient == (otherParameters?.AllowWebClient ?? throw new ArgumentNullException(nameof(otherParameters)))
&& SecurityLevel == otherParameters.SecurityLevel
&& Visibility == otherParameters.Visibility
&& Port == otherParameters.Port
&& TopicRequestTimeout == otherParameters.TopicRequestTimeout
&& AdditionalParameters == otherParameters.AdditionalParameters; // We intentionally don't check StartupTimeout or heartbeat seconds as it doesn't matter in terms of the watchdog
@@ -29,12 +29,19 @@ namespace Tgstation.Server.Api.Models.Response
public WatchdogStatus? Status { get; set; }
/// <summary>
/// The current <see cref="DreamDaemonSecurity"/> of <see cref="DreamDaemonResponse"/>. May be downgraded due to requirements of <see cref="ActiveCompileJob"/>.
/// The current <see cref="DreamDaemonSecurity"/>. May be upgraded. due to requirements of <see cref="ActiveCompileJob"/>.
/// </summary>
[EnumDataType(typeof(DreamDaemonSecurity))]
[ResponseOptions]
public DreamDaemonSecurity? CurrentSecurity { get; set; }
/// <summary>
/// The current <see cref="DreamDaemonVisibility"/>.
/// </summary>
[EnumDataType(typeof(DreamDaemonVisibility))]
[ResponseOptions]
public DreamDaemonVisibility? CurrentVisibility { get; set; }
/// <summary>
/// The port the running <see cref="DreamDaemonResponse"/> instance is set to.
/// </summary>
@@ -92,5 +92,10 @@ namespace Tgstation.Server.Api.Rights
/// User can change <see cref="Models.Internal.DreamDaemonLaunchParameters.AdditionalParameters"/>.
/// </summary>
SetAdditionalParameters = 32768,
/// <summary>
/// User set <see cref="Models.Internal.DreamDaemonLaunchParameters.Visibility"/>
/// </summary>
SetVisibility = 65536,
}
}
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "3.1.16",
"version": "3.1.18",
"commands": [
"dotnet-ef"
]
@@ -715,6 +715,7 @@ namespace Tgstation.Server.Host.Components.Deployment
AllowWebClient = false,
Port = portToUse,
SecurityLevel = securityLevel,
Visibility = DreamDaemonVisibility.Invisible,
StartupTimeout = timeout,
TopicRequestTimeout = 0, // not used
HeartbeatSeconds = 0, // not used
@@ -44,6 +44,11 @@ namespace Tgstation.Server.Host.Components.Interop.Bridge
/// </summary>
public DreamDaemonSecurity? SecurityLevel { get; }
/// <summary>
/// The <see cref="DreamDaemonSecurity"/> level of the launch.
/// </summary>
public DreamDaemonVisibility? Visibility { get; }
/// <summary>
/// The <see cref="TestMergeInformation"/>s in the launch.
/// </summary>
@@ -57,6 +62,7 @@ namespace Tgstation.Server.Host.Components.Interop.Bridge
/// <param name="serverVersion">The value of <see cref="ServerVersion"/>.</param>
/// <param name="instanceName">The value of <see cref="InstanceName"/>.</param>
/// <param name="securityLevel">The value of <see cref="SecurityLevel"/>.</param>
/// <param name="visibility">The value of <see cref="Visibility"/>.</param>
/// <param name="serverPort">The value of <see cref="ServerPort"/>.</param>
/// <param name="apiValidateOnly">The value of <see cref="ApiValidateOnly"/>.</param>
public RuntimeInformation(
@@ -65,6 +71,7 @@ namespace Tgstation.Server.Host.Components.Interop.Bridge
Version serverVersion,
string instanceName,
DreamDaemonSecurity? securityLevel,
DreamDaemonVisibility? visibility,
ushort serverPort,
bool apiValidateOnly)
: base(chatTrackingContext?.Channels ?? throw new ArgumentNullException(nameof(chatTrackingContext)))
@@ -92,6 +99,7 @@ namespace Tgstation.Server.Host.Components.Interop.Bridge
InstanceName = instanceName ?? throw new ArgumentNullException(nameof(instanceName));
SecurityLevel = securityLevel;
Visibility = visibility;
ServerPort = serverPort;
ApiValidateOnly = apiValidateOnly;
}
@@ -73,6 +73,7 @@ namespace Tgstation.Server.Host.Components.Session
AccessIdentifier = accessIdentifier ?? throw new ArgumentNullException(nameof(accessIdentifier));
LaunchSecurityLevel = runtimeInformation.SecurityLevel.Value;
LaunchVisibility = runtimeInformation.Visibility.Value;
Port = port;
runtimeInformationLock = new object();
@@ -402,6 +402,7 @@ namespace Tgstation.Server.Host.Components.Session
ReattachInformation.RuntimeInformation.ServerVersion,
ReattachInformation.RuntimeInformation.InstanceName,
ReattachInformation.RuntimeInformation.SecurityLevel,
ReattachInformation.RuntimeInformation.Visibility,
ReattachInformation.RuntimeInformation.ServerPort,
ReattachInformation.RuntimeInformation.ApiValidateOnly);
@@ -120,6 +120,22 @@ namespace Tgstation.Server.Host.Components.Session
};
}
/// <summary>
/// Change a given <paramref name="visibility"/> into the appropriate DreamDaemon command line word.
/// </summary>
/// <param name="visibility">The <see cref="DreamDaemonVisibility"/> level to change.</param>
/// <returns>A <see cref="string"/> representation of the command line parameter.</returns>
static string VisibilityWord(DreamDaemonVisibility visibility)
{
return visibility switch
{
DreamDaemonVisibility.Public => "public",
DreamDaemonVisibility.Private => "private",
DreamDaemonVisibility.Invisible => "invisible",
_ => throw new ArgumentOutOfRangeException(nameof(visibility), visibility, String.Format(CultureInfo.InvariantCulture, "Bad DreamDaemon visibility level: {0}", visibility)),
};
}
/// <summary>
/// Check if a given <paramref name="port"/> can be bound to.
/// </summary>
@@ -207,9 +223,16 @@ namespace Tgstation.Server.Host.Components.Session
break;
case DreamDaemonSecurity.Safe:
if (launchParameters.SecurityLevel == DreamDaemonSecurity.Ultrasafe)
{
logger.LogTrace("Boosting security level to minimum of Safe");
launchParameters.SecurityLevel = DreamDaemonSecurity.Safe;
}
break;
case DreamDaemonSecurity.Trusted:
if (launchParameters.SecurityLevel != DreamDaemonSecurity.Trusted)
logger.LogTrace("Boosting security level to minimum of Trusted");
launchParameters.SecurityLevel = DreamDaemonSecurity.Trusted;
break;
default:
@@ -246,8 +269,6 @@ namespace Tgstation.Server.Host.Components.Session
if (!String.IsNullOrEmpty(launchParameters.AdditionalParameters))
parameters = $"{parameters}&{launchParameters.AdditionalParameters}";
var visibility = apiValidate ? "invisible" : "public";
// important to run on all ports to allow port changing
Guid? logFileGuid = null;
var arguments = String.Format(
@@ -257,7 +278,7 @@ namespace Tgstation.Server.Host.Components.Session
launchParameters.Port.Value,
launchParameters.AllowWebClient.Value ? "-webclient " : String.Empty,
SecurityWord(launchParameters.SecurityLevel.Value),
visibility,
VisibilityWord(launchParameters.Visibility.Value),
platformIdentifier.IsWindows
? $" -log {logFileGuid = Guid.NewGuid()}"
: String.Empty, // Just use stdout on linux
@@ -333,6 +354,7 @@ namespace Tgstation.Server.Host.Components.Session
dmbProvider,
chatTrackingContext,
launchParameters.SecurityLevel.Value,
launchParameters.Visibility.Value,
apiValidate);
var reattachInformation = new ReattachInformation(
@@ -429,6 +451,7 @@ namespace Tgstation.Server.Host.Components.Session
reattachInformation.Dmb,
chatTrackingContext,
null,
null,
false);
reattachInformation.SetRuntimeInformation(runtimeInformation);
@@ -476,12 +499,14 @@ namespace Tgstation.Server.Host.Components.Session
/// <param name="dmbProvider">The <see cref="IDmbProvider"/>.</param>
/// <param name="chatTrackingContext">The <see cref="IChatTrackingContext"/>.</param>
/// <param name="securityLevel">The <see cref="DreamDaemonSecurity"/> level if any.</param>
/// <param name="visibility">The <see cref="DreamDaemonVisibility"/> if any.</param>
/// <param name="apiValidateOnly">The value of <see cref="RuntimeInformation.ApiValidateOnly"/>.</param>
/// <returns>A new <see cref="RuntimeInformation"/> class.</returns>
RuntimeInformation CreateRuntimeInformation(
IDmbProvider dmbProvider,
IChatTrackingContext chatTrackingContext,
DreamDaemonSecurity? securityLevel,
DreamDaemonVisibility? visibility,
bool apiValidateOnly)
=> new RuntimeInformation(
chatTrackingContext,
@@ -489,6 +514,7 @@ namespace Tgstation.Server.Host.Components.Session
assemblyInformationProvider.Version,
instance.Name,
securityLevel,
visibility,
serverPortProvider.HttpApiPort,
apiValidateOnly);
@@ -82,6 +82,7 @@ namespace Tgstation.Server.Host.Components.Session
ProcessId = reattachInformation.ProcessId,
RebootState = reattachInformation.RebootState,
LaunchSecurityLevel = reattachInformation.LaunchSecurityLevel,
LaunchVisibility = reattachInformation.LaunchVisibility,
};
db.ReattachInformations.Add(dbReattachInfo);
@@ -144,7 +144,9 @@ namespace Tgstation.Server.Host.Controllers
| DreamDaemonRights.Start
| DreamDaemonRights.SetStartupTimeout
| DreamDaemonRights.SetHeartbeatInterval
| DreamDaemonRights.SetTopicTimeout)]
| DreamDaemonRights.SetTopicTimeout
| DreamDaemonRights.SetAdditionalParameters
| DreamDaemonRights.SetVisibility)]
[ProducesResponseType(typeof(DreamDaemonResponse), 200)]
[ProducesResponseType(typeof(ErrorMessageResponse), 410)]
#pragma warning disable CA1502 // TODO: Decomplexify
@@ -210,6 +212,7 @@ namespace Tgstation.Server.Host.Controllers
|| CheckModified(x => x.AutoStart, DreamDaemonRights.SetAutoStart)
|| CheckModified(x => x.Port, DreamDaemonRights.SetPort)
|| CheckModified(x => x.SecurityLevel, DreamDaemonRights.SetSecurity)
|| CheckModified(x => x.Visibility, DreamDaemonRights.SetVisibility)
|| (model.SoftRestart.HasValue && !AuthenticationContext.InstancePermissionSet.DreamDaemonRights.Value.HasFlag(DreamDaemonRights.SoftRestart))
|| (model.SoftShutdown.HasValue && !AuthenticationContext.InstancePermissionSet.DreamDaemonRights.Value.HasFlag(DreamDaemonRights.SoftShutdown))
|| CheckModified(x => x.StartupTimeout, DreamDaemonRights.SetStartupTimeout)
@@ -341,11 +344,13 @@ namespace Tgstation.Server.Host.Controllers
result.AutoStart = settings.AutoStart.Value;
result.CurrentPort = llp?.Port.Value;
result.CurrentSecurity = llp?.SecurityLevel.Value;
result.CurrentVisibility = llp?.Visibility.Value;
result.CurrentAllowWebclient = llp?.AllowWebClient.Value;
result.Port = settings.Port.Value;
result.AllowWebClient = settings.AllowWebClient.Value;
result.Status = dd.Status;
result.SecurityLevel = settings.SecurityLevel.Value;
result.Visibility = settings.Visibility.Value;
result.SoftRestart = rstate == RebootState.Restart;
result.SoftShutdown = rstate == RebootState.Shutdown;
result.StartupTimeout = settings.StartupTimeout.Value;
@@ -716,6 +716,7 @@ namespace Tgstation.Server.Host.Controllers
AutoStart = false,
Port = ddPort,
SecurityLevel = DreamDaemonSecurity.Safe,
Visibility = DreamDaemonVisibility.Public,
StartupTimeout = 60,
HeartbeatSeconds = 60,
TopicRequestTimeout = generalConfiguration.ByondTopicTimeout,
@@ -379,22 +379,22 @@ namespace Tgstation.Server.Host.Database
/// <summary>
/// Used by unit tests to remind us to setup the correct MSSQL migration downgrades.
/// </summary>
internal static readonly Type MSLatestMigration = typeof(MSTruncateInstanceNames);
internal static readonly Type MSLatestMigration = typeof(MSAddDreamDaemonVisibility);
/// <summary>
/// Used by unit tests to remind us to setup the correct MYSQL migration downgrades.
/// </summary>
internal static readonly Type MYLatestMigration = typeof(MYTruncateInstanceNames);
internal static readonly Type MYLatestMigration = typeof(MYAddDreamDaemonVisibility);
/// <summary>
/// Used by unit tests to remind us to setup the correct PostgresSQL migration downgrades.
/// </summary>
internal static readonly Type PGLatestMigration = typeof(PGTruncateInstanceNames);
internal static readonly Type PGLatestMigration = typeof(PGAddDreamDaemonVisibility);
/// <summary>
/// Used by unit tests to remind us to setup the correct SQLite migration downgrades.
/// </summary>
internal static readonly Type SLLatestMigration = typeof(SLAddRevInfoTimestamp);
internal static readonly Type SLLatestMigration = typeof(SLAddDreamDaemonVisibility);
/// <inheritdoc />
#pragma warning disable CA1502 // Cyclomatic complexity
@@ -422,6 +422,15 @@ namespace Tgstation.Server.Host.Database
// Update this with new migrations as they are made
string targetMigration = null;
if (targetVersion < new Version(4, 14, 0))
targetMigration = currentDatabaseType switch
{
DatabaseType.MySql => nameof(MYTruncateInstanceNames),
DatabaseType.PostgresSql => nameof(PGTruncateInstanceNames),
DatabaseType.SqlServer => nameof(MSTruncateInstanceNames),
DatabaseType.Sqlite => nameof(SLAddRevInfoTimestamp),
_ => throw new ArgumentException($"Invalid DatabaseType: {currentDatabaseType}", nameof(currentDatabaseType)),
};
if (targetVersion < new Version(4, 10, 0))
targetMigration = currentDatabaseType switch
{
@@ -0,0 +1,908 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Tgstation.Server.Host.Database.Migrations
{
[DbContext(typeof(SqlServerDatabaseContext))]
[Migration("20210825163342_MSAddDreamDaemonVisibility")]
partial class MSAddDreamDaemonVisibility
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.18")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("ChannelLimit")
.HasColumnType("int");
b.Property<string>("ConnectionString")
.IsRequired()
.HasColumnType("nvarchar(max)")
.HasMaxLength(10000);
b.Property<bool?>("Enabled")
.HasColumnType("bit");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(100)")
.HasMaxLength(100);
b.Property<int>("Provider")
.HasColumnType("int");
b.Property<long>("ReconnectionInterval")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("InstanceId", "Name")
.IsUnique();
b.ToTable("ChatBots");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<long>("ChatSettingsId")
.HasColumnType("bigint");
b.Property<decimal?>("DiscordChannelId")
.HasColumnType("decimal(20,0)");
b.Property<string>("IrcChannel")
.HasColumnType("nvarchar(100)")
.HasMaxLength(100);
b.Property<bool?>("IsAdminChannel")
.IsRequired()
.HasColumnType("bit");
b.Property<bool?>("IsUpdatesChannel")
.IsRequired()
.HasColumnType("bit");
b.Property<bool?>("IsWatchdogChannel")
.IsRequired()
.HasColumnType("bit");
b.Property<string>("Tag")
.HasColumnType("nvarchar(max)")
.HasMaxLength(10000);
b.HasKey("Id");
b.HasIndex("ChatSettingsId", "DiscordChannelId")
.IsUnique()
.HasFilter("[DiscordChannelId] IS NOT NULL");
b.HasIndex("ChatSettingsId", "IrcChannel")
.IsUnique()
.HasFilter("[IrcChannel] IS NOT NULL");
b.ToTable("ChatChannels");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ByondVersion")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("DMApiMajorVersion")
.HasColumnType("int");
b.Property<int?>("DMApiMinorVersion")
.HasColumnType("int");
b.Property<int?>("DMApiPatchVersion")
.HasColumnType("int");
b.Property<Guid?>("DirectoryName")
.IsRequired()
.HasColumnType("uniqueidentifier");
b.Property<string>("DmeName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("GitHubDeploymentId")
.HasColumnType("int");
b.Property<long?>("GitHubRepoId")
.HasColumnType("bigint");
b.Property<long>("JobId")
.HasColumnType("bigint");
b.Property<int?>("MinimumSecurityLevel")
.HasColumnType("int");
b.Property<string>("Output")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("RepositoryOrigin")
.HasColumnType("nvarchar(max)");
b.Property<long>("RevisionInformationId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("DirectoryName");
b.HasIndex("JobId")
.IsUnique();
b.HasIndex("RevisionInformationId");
b.ToTable("CompileJobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("AdditionalParameters")
.IsRequired()
.HasColumnType("nvarchar(max)")
.HasMaxLength(10000);
b.Property<bool?>("AllowWebClient")
.IsRequired()
.HasColumnType("bit");
b.Property<bool?>("AutoStart")
.IsRequired()
.HasColumnType("bit");
b.Property<long>("HeartbeatSeconds")
.HasColumnType("bigint");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<int>("Port")
.HasColumnType("int");
b.Property<int>("SecurityLevel")
.HasColumnType("int");
b.Property<long>("StartupTimeout")
.HasColumnType("bigint");
b.Property<long>("TopicRequestTimeout")
.HasColumnType("bigint");
b.Property<int>("Visibility")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamDaemonSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("ApiValidationPort")
.HasColumnType("int");
b.Property<int>("ApiValidationSecurityLevel")
.HasColumnType("int");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("ProjectName")
.HasColumnType("nvarchar(max)")
.HasMaxLength(10000);
b.Property<bool?>("RequireDMApiValidation")
.IsRequired()
.HasColumnType("bit");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamMakerSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<long>("AutoUpdateInterval")
.HasColumnType("bigint");
b.Property<int>("ChatBotLimit")
.HasColumnType("int");
b.Property<int>("ConfigurationType")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(100)")
.HasMaxLength(100);
b.Property<bool?>("Online")
.IsRequired()
.HasColumnType("bit");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.Property<string>("SwarmIdentifer")
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("Path", "SwarmIdentifer")
.IsUnique()
.HasFilter("[SwarmIdentifer] IS NOT NULL");
b.ToTable("Instances");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<decimal>("ByondRights")
.HasColumnType("decimal(20,0)");
b.Property<decimal>("ChatBotRights")
.HasColumnType("decimal(20,0)");
b.Property<decimal>("ConfigurationRights")
.HasColumnType("decimal(20,0)");
b.Property<decimal>("DreamDaemonRights")
.HasColumnType("decimal(20,0)");
b.Property<decimal>("DreamMakerRights")
.HasColumnType("decimal(20,0)");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<decimal>("InstancePermissionSetRights")
.HasColumnType("decimal(20,0)");
b.Property<long>("PermissionSetId")
.HasColumnType("bigint");
b.Property<decimal>("RepositoryRights")
.HasColumnType("decimal(20,0)");
b.HasKey("Id");
b.HasIndex("InstanceId");
b.HasIndex("PermissionSetId", "InstanceId")
.IsUnique();
b.ToTable("InstancePermissionSets");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<decimal?>("CancelRight")
.HasColumnType("decimal(20,0)");
b.Property<decimal?>("CancelRightsType")
.HasColumnType("decimal(20,0)");
b.Property<bool?>("Cancelled")
.IsRequired()
.HasColumnType("bit");
b.Property<long?>("CancelledById")
.HasColumnType("bigint");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<long?>("ErrorCode")
.HasColumnType("bigint");
b.Property<string>("ExceptionDetails")
.HasColumnType("nvarchar(max)");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("StartedAt")
.IsRequired()
.HasColumnType("datetimeoffset");
b.Property<long>("StartedById")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("StoppedAt")
.HasColumnType("datetimeoffset");
b.HasKey("Id");
b.HasIndex("CancelledById");
b.HasIndex("InstanceId");
b.HasIndex("StartedById");
b.ToTable("Jobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ExternalUserId")
.IsRequired()
.HasColumnType("nvarchar(100)")
.HasMaxLength(100);
b.Property<int>("Provider")
.HasColumnType("int");
b.Property<long?>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("UserId");
b.HasIndex("Provider", "ExternalUserId")
.IsUnique();
b.ToTable("OAuthConnections");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<decimal>("AdministrationRights")
.HasColumnType("decimal(20,0)");
b.Property<long?>("GroupId")
.HasColumnType("bigint");
b.Property<decimal>("InstanceManagerRights")
.HasColumnType("decimal(20,0)");
b.Property<long?>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("GroupId")
.IsUnique()
.HasFilter("[GroupId] IS NOT NULL");
b.HasIndex("UserId")
.IsUnique()
.HasFilter("[UserId] IS NOT NULL");
b.ToTable("PermissionSets");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("AccessIdentifier")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<long>("CompileJobId")
.HasColumnType("bigint");
b.Property<int>("LaunchSecurityLevel")
.HasColumnType("int");
b.Property<int>("LaunchVisibility")
.HasColumnType("int");
b.Property<int>("Port")
.HasColumnType("int");
b.Property<int>("ProcessId")
.HasColumnType("int");
b.Property<int>("RebootState")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CompileJobId");
b.ToTable("ReattachInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("AccessToken")
.HasColumnType("nvarchar(max)")
.HasMaxLength(10000);
b.Property<string>("AccessUser")
.HasColumnType("nvarchar(max)")
.HasMaxLength(10000);
b.Property<bool?>("AutoUpdatesKeepTestMerges")
.IsRequired()
.HasColumnType("bit");
b.Property<bool?>("AutoUpdatesSynchronize")
.IsRequired()
.HasColumnType("bit");
b.Property<string>("CommitterEmail")
.IsRequired()
.HasColumnType("nvarchar(max)")
.HasMaxLength(10000);
b.Property<string>("CommitterName")
.IsRequired()
.HasColumnType("nvarchar(max)")
.HasMaxLength(10000);
b.Property<bool?>("CreateGitHubDeployments")
.IsRequired()
.HasColumnType("bit");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<bool?>("PostTestMergeComment")
.IsRequired()
.HasColumnType("bit");
b.Property<bool?>("PushTestMergeCommits")
.IsRequired()
.HasColumnType("bit");
b.Property<bool?>("ShowTestMergeCommitters")
.IsRequired()
.HasColumnType("bit");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("RepositorySettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<long>("RevisionInformationId")
.HasColumnType("bigint");
b.Property<long>("TestMergeId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("RevisionInformationId");
b.HasIndex("TestMergeId");
b.ToTable("RevInfoTestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("CommitSha")
.IsRequired()
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("OriginCommitSha")
.IsRequired()
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<DateTimeOffset>("Timestamp")
.HasColumnType("datetimeoffset");
b.HasKey("Id");
b.HasIndex("InstanceId", "CommitSha")
.IsUnique();
b.ToTable("RevisionInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Author")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("BodyAtMerge")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Comment")
.HasColumnType("nvarchar(max)")
.HasMaxLength(10000);
b.Property<DateTimeOffset>("MergedAt")
.HasColumnType("datetimeoffset");
b.Property<long>("MergedById")
.HasColumnType("bigint");
b.Property<int>("Number")
.HasColumnType("int");
b.Property<long?>("PrimaryRevisionInformationId")
.IsRequired()
.HasColumnType("bigint");
b.Property<string>("TargetCommitSha")
.IsRequired()
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("TitleAtMerge")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("MergedById");
b.HasIndex("PrimaryRevisionInformationId")
.IsUnique();
b.ToTable("TestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("CanonicalName")
.IsRequired()
.HasColumnType("nvarchar(100)")
.HasMaxLength(100);
b.Property<DateTimeOffset?>("CreatedAt")
.IsRequired()
.HasColumnType("datetimeoffset");
b.Property<long?>("CreatedById")
.HasColumnType("bigint");
b.Property<bool?>("Enabled")
.IsRequired()
.HasColumnType("bit");
b.Property<long?>("GroupId")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("LastPasswordUpdate")
.HasColumnType("datetimeoffset");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(100)")
.HasMaxLength(100);
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("SystemIdentifier")
.HasColumnType("nvarchar(100)")
.HasMaxLength(100);
b.HasKey("Id");
b.HasIndex("CanonicalName")
.IsUnique();
b.HasIndex("CreatedById");
b.HasIndex("GroupId");
b.HasIndex("SystemIdentifier")
.IsUnique()
.HasFilter("[SystemIdentifier] IS NOT NULL");
b.ToTable("Users");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.UserGroup", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(100)")
.HasMaxLength(100);
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Groups");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("ChatSettings")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings")
.WithMany("Channels")
.HasForeignKey("ChatSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Job", "Job")
.WithOne()
.HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("CompileJobs")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.ClientNoAction)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamDaemonSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamMakerSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("InstancePermissionSets")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.PermissionSet", "PermissionSet")
.WithMany("InstancePermissionSets")
.HasForeignKey("PermissionSetId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy")
.WithMany()
.HasForeignKey("CancelledById");
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("Jobs")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy")
.WithMany()
.HasForeignKey("StartedById")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "User")
.WithMany("OAuthConnections")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
{
b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
.WithOne("PermissionSet")
.HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "GroupId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Tgstation.Server.Host.Models.User", "User")
.WithOne("PermissionSet")
.HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob")
.WithMany()
.HasForeignKey("CompileJobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("RepositorySettings")
.HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("ActiveTestMerges")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge")
.WithMany("RevisonInformations")
.HasForeignKey("TestMergeId")
.OnDelete(DeleteBehavior.ClientNoAction)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("RevisionInformations")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy")
.WithMany("TestMerges")
.HasForeignKey("MergedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation")
.WithOne("PrimaryTestMerge")
.HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy")
.WithMany("CreatedUsers")
.HasForeignKey("CreatedById");
b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
.WithMany("Users")
.HasForeignKey("GroupId");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,46 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Tgstation.Server.Host.Database.Migrations
{
/// <summary>
/// Add DreamDaemon visibilty for MSSQL.
/// </summary>
public partial class MSAddDreamDaemonVisibility : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
migrationBuilder.AddColumn<int>(
name: "LaunchVisibility",
table: "ReattachInformations",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "Visibility",
table: "DreamDaemonSettings",
nullable: false,
defaultValue: 0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
migrationBuilder.DropColumn(
name: "LaunchVisibility",
table: "ReattachInformations");
migrationBuilder.DropColumn(
name: "Visibility",
table: "DreamDaemonSettings");
}
}
}
@@ -0,0 +1,892 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Tgstation.Server.Host.Database.Migrations
{
[DbContext(typeof(MySqlDatabaseContext))]
[Migration("20210825163433_MYAddDreamDaemonVisibility")]
partial class MYAddDreamDaemonVisibility
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.18")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<ushort?>("ChannelLimit")
.IsRequired()
.HasColumnType("smallint unsigned");
b.Property<string>("ConnectionString")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(10000);
b.Property<bool?>("Enabled")
.HasColumnType("tinyint(1)");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.Property<int>("Provider")
.HasColumnType("int");
b.Property<uint?>("ReconnectionInterval")
.IsRequired()
.HasColumnType("int unsigned");
b.HasKey("Id");
b.HasIndex("InstanceId", "Name")
.IsUnique();
b.ToTable("ChatBots");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<long>("ChatSettingsId")
.HasColumnType("bigint");
b.Property<ulong?>("DiscordChannelId")
.HasColumnType("bigint unsigned");
b.Property<string>("IrcChannel")
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.Property<bool?>("IsAdminChannel")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<bool?>("IsUpdatesChannel")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<bool?>("IsWatchdogChannel")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<string>("Tag")
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(10000);
b.HasKey("Id");
b.HasIndex("ChatSettingsId", "DiscordChannelId")
.IsUnique();
b.HasIndex("ChatSettingsId", "IrcChannel")
.IsUnique();
b.ToTable("ChatChannels");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ByondVersion")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int?>("DMApiMajorVersion")
.HasColumnType("int");
b.Property<int?>("DMApiMinorVersion")
.HasColumnType("int");
b.Property<int?>("DMApiPatchVersion")
.HasColumnType("int");
b.Property<Guid?>("DirectoryName")
.IsRequired()
.HasColumnType("char(36)");
b.Property<string>("DmeName")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int?>("GitHubDeploymentId")
.HasColumnType("int");
b.Property<long?>("GitHubRepoId")
.HasColumnType("bigint");
b.Property<long>("JobId")
.HasColumnType("bigint");
b.Property<int?>("MinimumSecurityLevel")
.HasColumnType("int");
b.Property<string>("Output")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<string>("RepositoryOrigin")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<long>("RevisionInformationId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("DirectoryName");
b.HasIndex("JobId")
.IsUnique();
b.HasIndex("RevisionInformationId");
b.ToTable("CompileJobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("AdditionalParameters")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(10000);
b.Property<bool?>("AllowWebClient")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<bool?>("AutoStart")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<uint?>("HeartbeatSeconds")
.IsRequired()
.HasColumnType("int unsigned");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<ushort?>("Port")
.IsRequired()
.HasColumnType("smallint unsigned");
b.Property<int>("SecurityLevel")
.HasColumnType("int");
b.Property<uint?>("StartupTimeout")
.IsRequired()
.HasColumnType("int unsigned");
b.Property<uint?>("TopicRequestTimeout")
.IsRequired()
.HasColumnType("int unsigned");
b.Property<int>("Visibility")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamDaemonSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<ushort?>("ApiValidationPort")
.IsRequired()
.HasColumnType("smallint unsigned");
b.Property<int>("ApiValidationSecurityLevel")
.HasColumnType("int");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("ProjectName")
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(10000);
b.Property<bool?>("RequireDMApiValidation")
.IsRequired()
.HasColumnType("tinyint(1)");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamMakerSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<uint?>("AutoUpdateInterval")
.IsRequired()
.HasColumnType("int unsigned");
b.Property<ushort?>("ChatBotLimit")
.IsRequired()
.HasColumnType("smallint unsigned");
b.Property<int>("ConfigurationType")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.Property<bool?>("Online")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("varchar(255) CHARACTER SET utf8mb4");
b.Property<string>("SwarmIdentifer")
.HasColumnType("varchar(255) CHARACTER SET utf8mb4");
b.HasKey("Id");
b.HasIndex("Path", "SwarmIdentifer")
.IsUnique();
b.ToTable("Instances");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<ulong>("ByondRights")
.HasColumnType("bigint unsigned");
b.Property<ulong>("ChatBotRights")
.HasColumnType("bigint unsigned");
b.Property<ulong>("ConfigurationRights")
.HasColumnType("bigint unsigned");
b.Property<ulong>("DreamDaemonRights")
.HasColumnType("bigint unsigned");
b.Property<ulong>("DreamMakerRights")
.HasColumnType("bigint unsigned");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<ulong>("InstancePermissionSetRights")
.HasColumnType("bigint unsigned");
b.Property<long>("PermissionSetId")
.HasColumnType("bigint");
b.Property<ulong>("RepositoryRights")
.HasColumnType("bigint unsigned");
b.HasKey("Id");
b.HasIndex("InstanceId");
b.HasIndex("PermissionSetId", "InstanceId")
.IsUnique();
b.ToTable("InstancePermissionSets");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<ulong?>("CancelRight")
.HasColumnType("bigint unsigned");
b.Property<ulong?>("CancelRightsType")
.HasColumnType("bigint unsigned");
b.Property<bool?>("Cancelled")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<long?>("CancelledById")
.HasColumnType("bigint");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<uint?>("ErrorCode")
.HasColumnType("int unsigned");
b.Property<string>("ExceptionDetails")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("StartedAt")
.IsRequired()
.HasColumnType("datetime(6)");
b.Property<long>("StartedById")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("StoppedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("CancelledById");
b.HasIndex("InstanceId");
b.HasIndex("StartedById");
b.ToTable("Jobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ExternalUserId")
.IsRequired()
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.Property<int>("Provider")
.HasColumnType("int");
b.Property<long?>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("UserId");
b.HasIndex("Provider", "ExternalUserId")
.IsUnique();
b.ToTable("OAuthConnections");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<ulong>("AdministrationRights")
.HasColumnType("bigint unsigned");
b.Property<long?>("GroupId")
.HasColumnType("bigint");
b.Property<ulong>("InstanceManagerRights")
.HasColumnType("bigint unsigned");
b.Property<long?>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("GroupId")
.IsUnique();
b.HasIndex("UserId")
.IsUnique();
b.ToTable("PermissionSets");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("AccessIdentifier")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<long>("CompileJobId")
.HasColumnType("bigint");
b.Property<int>("LaunchSecurityLevel")
.HasColumnType("int");
b.Property<int>("LaunchVisibility")
.HasColumnType("int");
b.Property<ushort>("Port")
.HasColumnType("smallint unsigned");
b.Property<int>("ProcessId")
.HasColumnType("int");
b.Property<int>("RebootState")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CompileJobId");
b.ToTable("ReattachInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("AccessToken")
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(10000);
b.Property<string>("AccessUser")
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(10000);
b.Property<bool?>("AutoUpdatesKeepTestMerges")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<bool?>("AutoUpdatesSynchronize")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<string>("CommitterEmail")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(10000);
b.Property<string>("CommitterName")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(10000);
b.Property<bool?>("CreateGitHubDeployments")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<bool?>("PostTestMergeComment")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<bool?>("PushTestMergeCommits")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<bool?>("ShowTestMergeCommitters")
.IsRequired()
.HasColumnType("tinyint(1)");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("RepositorySettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<long>("RevisionInformationId")
.HasColumnType("bigint");
b.Property<long>("TestMergeId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("RevisionInformationId");
b.HasIndex("TestMergeId");
b.ToTable("RevInfoTestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("CommitSha")
.IsRequired()
.HasColumnType("varchar(40) CHARACTER SET utf8mb4")
.HasMaxLength(40);
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("OriginCommitSha")
.IsRequired()
.HasColumnType("varchar(40) CHARACTER SET utf8mb4")
.HasMaxLength(40);
b.Property<DateTimeOffset>("Timestamp")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("InstanceId", "CommitSha")
.IsUnique();
b.ToTable("RevisionInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Author")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<string>("BodyAtMerge")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<string>("Comment")
.HasColumnType("longtext CHARACTER SET utf8mb4")
.HasMaxLength(10000);
b.Property<DateTimeOffset>("MergedAt")
.HasColumnType("datetime(6)");
b.Property<long>("MergedById")
.HasColumnType("bigint");
b.Property<int>("Number")
.HasColumnType("int");
b.Property<long?>("PrimaryRevisionInformationId")
.IsRequired()
.HasColumnType("bigint");
b.Property<string>("TargetCommitSha")
.IsRequired()
.HasColumnType("varchar(40) CHARACTER SET utf8mb4")
.HasMaxLength(40);
b.Property<string>("TitleAtMerge")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.HasKey("Id");
b.HasIndex("MergedById");
b.HasIndex("PrimaryRevisionInformationId")
.IsUnique();
b.ToTable("TestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("CanonicalName")
.IsRequired()
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.Property<DateTimeOffset?>("CreatedAt")
.IsRequired()
.HasColumnType("datetime(6)");
b.Property<long?>("CreatedById")
.HasColumnType("bigint");
b.Property<bool?>("Enabled")
.IsRequired()
.HasColumnType("tinyint(1)");
b.Property<long?>("GroupId")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("LastPasswordUpdate")
.HasColumnType("datetime(6)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.Property<string>("PasswordHash")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<string>("SystemIdentifier")
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.HasKey("Id");
b.HasIndex("CanonicalName")
.IsUnique();
b.HasIndex("CreatedById");
b.HasIndex("GroupId");
b.HasIndex("SystemIdentifier")
.IsUnique();
b.ToTable("Users");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.UserGroup", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(100) CHARACTER SET utf8mb4")
.HasMaxLength(100);
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Groups");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("ChatSettings")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings")
.WithMany("Channels")
.HasForeignKey("ChatSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Job", "Job")
.WithOne()
.HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("CompileJobs")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamDaemonSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamMakerSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("InstancePermissionSets")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.PermissionSet", "PermissionSet")
.WithMany("InstancePermissionSets")
.HasForeignKey("PermissionSetId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy")
.WithMany()
.HasForeignKey("CancelledById");
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("Jobs")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy")
.WithMany()
.HasForeignKey("StartedById")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "User")
.WithMany("OAuthConnections")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
{
b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
.WithOne("PermissionSet")
.HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "GroupId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Tgstation.Server.Host.Models.User", "User")
.WithOne("PermissionSet")
.HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob")
.WithMany()
.HasForeignKey("CompileJobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("RepositorySettings")
.HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("ActiveTestMerges")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge")
.WithMany("RevisonInformations")
.HasForeignKey("TestMergeId")
.OnDelete(DeleteBehavior.ClientNoAction)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("RevisionInformations")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy")
.WithMany("TestMerges")
.HasForeignKey("MergedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation")
.WithOne("PrimaryTestMerge")
.HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy")
.WithMany("CreatedUsers")
.HasForeignKey("CreatedById");
b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
.WithMany("Users")
.HasForeignKey("GroupId");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,46 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Tgstation.Server.Host.Database.Migrations
{
/// <summary>
/// Add DreamDaemon visibilty for MYSQL.
/// </summary>
public partial class MYAddDreamDaemonVisibility : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
migrationBuilder.AddColumn<int>(
name: "LaunchVisibility",
table: "ReattachInformations",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "Visibility",
table: "DreamDaemonSettings",
nullable: false,
defaultValue: 0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
migrationBuilder.DropColumn(
name: "LaunchVisibility",
table: "ReattachInformations");
migrationBuilder.DropColumn(
name: "Visibility",
table: "DreamDaemonSettings");
}
}
}
@@ -0,0 +1,902 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Tgstation.Server.Host.Database.Migrations
{
[DbContext(typeof(PostgresSqlDatabaseContext))]
[Migration("20210825163520_PGAddDreamDaemonVisibility")]
partial class PGAddDreamDaemonVisibility
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "3.1.18")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<int>("ChannelLimit")
.HasColumnType("integer");
b.Property<string>("ConnectionString")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("Enabled")
.HasColumnType("boolean");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.Property<int>("Provider")
.HasColumnType("integer");
b.Property<long>("ReconnectionInterval")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("InstanceId", "Name")
.IsUnique();
b.ToTable("ChatBots");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long>("ChatSettingsId")
.HasColumnType("bigint");
b.Property<decimal?>("DiscordChannelId")
.HasColumnType("numeric(20,0)");
b.Property<string>("IrcChannel")
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.Property<bool?>("IsAdminChannel")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("IsUpdatesChannel")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("IsWatchdogChannel")
.IsRequired()
.HasColumnType("boolean");
b.Property<string>("Tag")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.HasKey("Id");
b.HasIndex("ChatSettingsId", "DiscordChannelId")
.IsUnique();
b.HasIndex("ChatSettingsId", "IrcChannel")
.IsUnique();
b.ToTable("ChatChannels");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("ByondVersion")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("DMApiMajorVersion")
.HasColumnType("integer");
b.Property<int?>("DMApiMinorVersion")
.HasColumnType("integer");
b.Property<int?>("DMApiPatchVersion")
.HasColumnType("integer");
b.Property<Guid?>("DirectoryName")
.IsRequired()
.HasColumnType("uuid");
b.Property<string>("DmeName")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("GitHubDeploymentId")
.HasColumnType("integer");
b.Property<long?>("GitHubRepoId")
.HasColumnType("bigint");
b.Property<long>("JobId")
.HasColumnType("bigint");
b.Property<int?>("MinimumSecurityLevel")
.HasColumnType("integer");
b.Property<string>("Output")
.IsRequired()
.HasColumnType("text");
b.Property<string>("RepositoryOrigin")
.HasColumnType("text");
b.Property<long>("RevisionInformationId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("DirectoryName");
b.HasIndex("JobId")
.IsUnique();
b.HasIndex("RevisionInformationId");
b.ToTable("CompileJobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("AdditionalParameters")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("AllowWebClient")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("AutoStart")
.IsRequired()
.HasColumnType("boolean");
b.Property<long>("HeartbeatSeconds")
.HasColumnType("bigint");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<int>("Port")
.HasColumnType("integer");
b.Property<int>("SecurityLevel")
.HasColumnType("integer");
b.Property<long>("StartupTimeout")
.HasColumnType("bigint");
b.Property<long>("TopicRequestTimeout")
.HasColumnType("bigint");
b.Property<int>("Visibility")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamDaemonSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<int>("ApiValidationPort")
.HasColumnType("integer");
b.Property<int>("ApiValidationSecurityLevel")
.HasColumnType("integer");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("ProjectName")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("RequireDMApiValidation")
.IsRequired()
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamMakerSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long>("AutoUpdateInterval")
.HasColumnType("bigint");
b.Property<int>("ChatBotLimit")
.HasColumnType("integer");
b.Property<int>("ConfigurationType")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.Property<bool?>("Online")
.IsRequired()
.HasColumnType("boolean");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("text");
b.Property<string>("SwarmIdentifer")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Path", "SwarmIdentifer")
.IsUnique();
b.ToTable("Instances");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<decimal>("ByondRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("ChatBotRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("ConfigurationRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("DreamDaemonRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("DreamMakerRights")
.HasColumnType("numeric(20,0)");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<decimal>("InstancePermissionSetRights")
.HasColumnType("numeric(20,0)");
b.Property<long>("PermissionSetId")
.HasColumnType("bigint");
b.Property<decimal>("RepositoryRights")
.HasColumnType("numeric(20,0)");
b.HasKey("Id");
b.HasIndex("InstanceId");
b.HasIndex("PermissionSetId", "InstanceId")
.IsUnique();
b.ToTable("InstancePermissionSets");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<decimal?>("CancelRight")
.HasColumnType("numeric(20,0)");
b.Property<decimal?>("CancelRightsType")
.HasColumnType("numeric(20,0)");
b.Property<bool?>("Cancelled")
.IsRequired()
.HasColumnType("boolean");
b.Property<long?>("CancelledById")
.HasColumnType("bigint");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<long?>("ErrorCode")
.HasColumnType("bigint");
b.Property<string>("ExceptionDetails")
.HasColumnType("text");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("StartedAt")
.IsRequired()
.HasColumnType("timestamp with time zone");
b.Property<long>("StartedById")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("StoppedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CancelledById");
b.HasIndex("InstanceId");
b.HasIndex("StartedById");
b.ToTable("Jobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("ExternalUserId")
.IsRequired()
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.Property<int>("Provider")
.HasColumnType("integer");
b.Property<long?>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("UserId");
b.HasIndex("Provider", "ExternalUserId")
.IsUnique();
b.ToTable("OAuthConnections");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<decimal>("AdministrationRights")
.HasColumnType("numeric(20,0)");
b.Property<long?>("GroupId")
.HasColumnType("bigint");
b.Property<decimal>("InstanceManagerRights")
.HasColumnType("numeric(20,0)");
b.Property<long?>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("GroupId")
.IsUnique();
b.HasIndex("UserId")
.IsUnique();
b.ToTable("PermissionSets");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("AccessIdentifier")
.IsRequired()
.HasColumnType("text");
b.Property<long>("CompileJobId")
.HasColumnType("bigint");
b.Property<int>("LaunchSecurityLevel")
.HasColumnType("integer");
b.Property<int>("LaunchVisibility")
.HasColumnType("integer");
b.Property<int>("Port")
.HasColumnType("integer");
b.Property<int>("ProcessId")
.HasColumnType("integer");
b.Property<int>("RebootState")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CompileJobId");
b.ToTable("ReattachInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("AccessToken")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<string>("AccessUser")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("AutoUpdatesKeepTestMerges")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("AutoUpdatesSynchronize")
.IsRequired()
.HasColumnType("boolean");
b.Property<string>("CommitterEmail")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<string>("CommitterName")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("CreateGitHubDeployments")
.IsRequired()
.HasColumnType("boolean");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<bool?>("PostTestMergeComment")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("PushTestMergeCommits")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("ShowTestMergeCommitters")
.IsRequired()
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("RepositorySettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long>("RevisionInformationId")
.HasColumnType("bigint");
b.Property<long>("TestMergeId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("RevisionInformationId");
b.HasIndex("TestMergeId");
b.ToTable("RevInfoTestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("CommitSha")
.IsRequired()
.HasColumnType("character varying(40)")
.HasMaxLength(40);
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("OriginCommitSha")
.IsRequired()
.HasColumnType("character varying(40)")
.HasMaxLength(40);
b.Property<DateTimeOffset>("Timestamp")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("InstanceId", "CommitSha")
.IsUnique();
b.ToTable("RevisionInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("Author")
.IsRequired()
.HasColumnType("text");
b.Property<string>("BodyAtMerge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Comment")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<DateTimeOffset>("MergedAt")
.HasColumnType("timestamp with time zone");
b.Property<long>("MergedById")
.HasColumnType("bigint");
b.Property<int>("Number")
.HasColumnType("integer");
b.Property<long?>("PrimaryRevisionInformationId")
.IsRequired()
.HasColumnType("bigint");
b.Property<string>("TargetCommitSha")
.IsRequired()
.HasColumnType("character varying(40)")
.HasMaxLength(40);
b.Property<string>("TitleAtMerge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("MergedById");
b.HasIndex("PrimaryRevisionInformationId")
.IsUnique();
b.ToTable("TestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("CanonicalName")
.IsRequired()
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.Property<DateTimeOffset?>("CreatedAt")
.IsRequired()
.HasColumnType("timestamp with time zone");
b.Property<long?>("CreatedById")
.HasColumnType("bigint");
b.Property<bool?>("Enabled")
.IsRequired()
.HasColumnType("boolean");
b.Property<long?>("GroupId")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("LastPasswordUpdate")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<string>("SystemIdentifier")
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.HasKey("Id");
b.HasIndex("CanonicalName")
.IsUnique();
b.HasIndex("CreatedById");
b.HasIndex("GroupId");
b.HasIndex("SystemIdentifier")
.IsUnique();
b.ToTable("Users");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.UserGroup", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Groups");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("ChatSettings")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings")
.WithMany("Channels")
.HasForeignKey("ChatSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Job", "Job")
.WithOne()
.HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("CompileJobs")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamDaemonSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamMakerSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("InstancePermissionSets")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.PermissionSet", "PermissionSet")
.WithMany("InstancePermissionSets")
.HasForeignKey("PermissionSetId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy")
.WithMany()
.HasForeignKey("CancelledById");
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("Jobs")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy")
.WithMany()
.HasForeignKey("StartedById")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "User")
.WithMany("OAuthConnections")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
{
b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
.WithOne("PermissionSet")
.HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "GroupId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Tgstation.Server.Host.Models.User", "User")
.WithOne("PermissionSet")
.HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob")
.WithMany()
.HasForeignKey("CompileJobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("RepositorySettings")
.HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("ActiveTestMerges")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge")
.WithMany("RevisonInformations")
.HasForeignKey("TestMergeId")
.OnDelete(DeleteBehavior.ClientNoAction)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("RevisionInformations")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy")
.WithMany("TestMerges")
.HasForeignKey("MergedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation")
.WithOne("PrimaryTestMerge")
.HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy")
.WithMany("CreatedUsers")
.HasForeignKey("CreatedById");
b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
.WithMany("Users")
.HasForeignKey("GroupId");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,46 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Tgstation.Server.Host.Database.Migrations
{
/// <summary>
/// Add DreamDaemon visibilty for PostgresSQL.
/// </summary>
public partial class PGAddDreamDaemonVisibility : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
migrationBuilder.AddColumn<int>(
name: "LaunchVisibility",
table: "ReattachInformations",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "Visibility",
table: "DreamDaemonSettings",
nullable: false,
defaultValue: 0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
migrationBuilder.DropColumn(
name: "LaunchVisibility",
table: "ReattachInformations");
migrationBuilder.DropColumn(
name: "Visibility",
table: "DreamDaemonSettings");
}
}
}
@@ -0,0 +1,891 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Tgstation.Server.Host.Database.Migrations
{
[DbContext(typeof(SqliteDatabaseContext))]
[Migration("20210825163612_SLAddDreamDaemonVisibility")]
partial class SLAddDreamDaemonVisibility
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.18");
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<ushort?>("ChannelLimit")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<string>("ConnectionString")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(10000);
b.Property<bool?>("Enabled")
.HasColumnType("INTEGER");
b.Property<long>("InstanceId")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(100);
b.Property<int>("Provider")
.HasColumnType("INTEGER");
b.Property<uint?>("ReconnectionInterval")
.IsRequired()
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("InstanceId", "Name")
.IsUnique();
b.ToTable("ChatBots");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<long>("ChatSettingsId")
.HasColumnType("INTEGER");
b.Property<ulong?>("DiscordChannelId")
.HasColumnType("INTEGER");
b.Property<string>("IrcChannel")
.HasColumnType("TEXT")
.HasMaxLength(100);
b.Property<bool?>("IsAdminChannel")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<bool?>("IsUpdatesChannel")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<bool?>("IsWatchdogChannel")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<string>("Tag")
.HasColumnType("TEXT")
.HasMaxLength(10000);
b.HasKey("Id");
b.HasIndex("ChatSettingsId", "DiscordChannelId")
.IsUnique();
b.HasIndex("ChatSettingsId", "IrcChannel")
.IsUnique();
b.ToTable("ChatChannels");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ByondVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int?>("DMApiMajorVersion")
.HasColumnType("INTEGER");
b.Property<int?>("DMApiMinorVersion")
.HasColumnType("INTEGER");
b.Property<int?>("DMApiPatchVersion")
.HasColumnType("INTEGER");
b.Property<Guid?>("DirectoryName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("DmeName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int?>("GitHubDeploymentId")
.HasColumnType("INTEGER");
b.Property<long?>("GitHubRepoId")
.HasColumnType("INTEGER");
b.Property<long>("JobId")
.HasColumnType("INTEGER");
b.Property<int?>("MinimumSecurityLevel")
.HasColumnType("INTEGER");
b.Property<string>("Output")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("RepositoryOrigin")
.HasColumnType("TEXT");
b.Property<long>("RevisionInformationId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("DirectoryName");
b.HasIndex("JobId")
.IsUnique();
b.HasIndex("RevisionInformationId");
b.ToTable("CompileJobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AdditionalParameters")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(10000);
b.Property<bool?>("AllowWebClient")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<bool?>("AutoStart")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<uint?>("HeartbeatSeconds")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<long>("InstanceId")
.HasColumnType("INTEGER");
b.Property<ushort?>("Port")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<int>("SecurityLevel")
.HasColumnType("INTEGER");
b.Property<uint?>("StartupTimeout")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<uint?>("TopicRequestTimeout")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<int>("Visibility")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamDaemonSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<ushort?>("ApiValidationPort")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<int>("ApiValidationSecurityLevel")
.HasColumnType("INTEGER");
b.Property<long>("InstanceId")
.HasColumnType("INTEGER");
b.Property<string>("ProjectName")
.HasColumnType("TEXT")
.HasMaxLength(10000);
b.Property<bool?>("RequireDMApiValidation")
.IsRequired()
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamMakerSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint?>("AutoUpdateInterval")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<ushort?>("ChatBotLimit")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<int>("ConfigurationType")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(100);
b.Property<bool?>("Online")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SwarmIdentifer")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("Path", "SwarmIdentifer")
.IsUnique();
b.ToTable("Instances");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<ulong>("ByondRights")
.HasColumnType("INTEGER");
b.Property<ulong>("ChatBotRights")
.HasColumnType("INTEGER");
b.Property<ulong>("ConfigurationRights")
.HasColumnType("INTEGER");
b.Property<ulong>("DreamDaemonRights")
.HasColumnType("INTEGER");
b.Property<ulong>("DreamMakerRights")
.HasColumnType("INTEGER");
b.Property<long>("InstanceId")
.HasColumnType("INTEGER");
b.Property<ulong>("InstancePermissionSetRights")
.HasColumnType("INTEGER");
b.Property<long>("PermissionSetId")
.HasColumnType("INTEGER");
b.Property<ulong>("RepositoryRights")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("InstanceId");
b.HasIndex("PermissionSetId", "InstanceId")
.IsUnique();
b.ToTable("InstancePermissionSets");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<ulong?>("CancelRight")
.HasColumnType("INTEGER");
b.Property<ulong?>("CancelRightsType")
.HasColumnType("INTEGER");
b.Property<bool?>("Cancelled")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<long?>("CancelledById")
.HasColumnType("INTEGER");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint?>("ErrorCode")
.HasColumnType("INTEGER");
b.Property<string>("ExceptionDetails")
.HasColumnType("TEXT");
b.Property<long>("InstanceId")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("StartedAt")
.IsRequired()
.HasColumnType("TEXT");
b.Property<long>("StartedById")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("StoppedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("CancelledById");
b.HasIndex("InstanceId");
b.HasIndex("StartedById");
b.ToTable("Jobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ExternalUserId")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(100);
b.Property<int>("Provider")
.HasColumnType("INTEGER");
b.Property<long?>("UserId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("UserId");
b.HasIndex("Provider", "ExternalUserId")
.IsUnique();
b.ToTable("OAuthConnections");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<ulong>("AdministrationRights")
.HasColumnType("INTEGER");
b.Property<long?>("GroupId")
.HasColumnType("INTEGER");
b.Property<ulong>("InstanceManagerRights")
.HasColumnType("INTEGER");
b.Property<long?>("UserId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("GroupId")
.IsUnique();
b.HasIndex("UserId")
.IsUnique();
b.ToTable("PermissionSets");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AccessIdentifier")
.IsRequired()
.HasColumnType("TEXT");
b.Property<long>("CompileJobId")
.HasColumnType("INTEGER");
b.Property<int>("LaunchSecurityLevel")
.HasColumnType("INTEGER");
b.Property<int>("LaunchVisibility")
.HasColumnType("INTEGER");
b.Property<ushort>("Port")
.HasColumnType("INTEGER");
b.Property<int>("ProcessId")
.HasColumnType("INTEGER");
b.Property<int>("RebootState")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("CompileJobId");
b.ToTable("ReattachInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AccessToken")
.HasColumnType("TEXT")
.HasMaxLength(10000);
b.Property<string>("AccessUser")
.HasColumnType("TEXT")
.HasMaxLength(10000);
b.Property<bool?>("AutoUpdatesKeepTestMerges")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<bool?>("AutoUpdatesSynchronize")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<string>("CommitterEmail")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(10000);
b.Property<string>("CommitterName")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(10000);
b.Property<bool?>("CreateGitHubDeployments")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<long>("InstanceId")
.HasColumnType("INTEGER");
b.Property<bool?>("PostTestMergeComment")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<bool?>("PushTestMergeCommits")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<bool?>("ShowTestMergeCommitters")
.IsRequired()
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("RepositorySettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<long>("RevisionInformationId")
.HasColumnType("INTEGER");
b.Property<long>("TestMergeId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("RevisionInformationId");
b.HasIndex("TestMergeId");
b.ToTable("RevInfoTestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("CommitSha")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(40);
b.Property<long>("InstanceId")
.HasColumnType("INTEGER");
b.Property<string>("OriginCommitSha")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(40);
b.Property<DateTimeOffset>("Timestamp")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("InstanceId", "CommitSha")
.IsUnique();
b.ToTable("RevisionInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Author")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("BodyAtMerge")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Comment")
.HasColumnType("TEXT")
.HasMaxLength(10000);
b.Property<DateTimeOffset>("MergedAt")
.HasColumnType("TEXT");
b.Property<long>("MergedById")
.HasColumnType("INTEGER");
b.Property<int>("Number")
.HasColumnType("INTEGER");
b.Property<long?>("PrimaryRevisionInformationId")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<string>("TargetCommitSha")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(40);
b.Property<string>("TitleAtMerge")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("MergedById");
b.HasIndex("PrimaryRevisionInformationId")
.IsUnique();
b.ToTable("TestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("CanonicalName")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(100);
b.Property<DateTimeOffset?>("CreatedAt")
.IsRequired()
.HasColumnType("TEXT");
b.Property<long?>("CreatedById")
.HasColumnType("INTEGER");
b.Property<bool?>("Enabled")
.IsRequired()
.HasColumnType("INTEGER");
b.Property<long?>("GroupId")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LastPasswordUpdate")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(100);
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("SystemIdentifier")
.HasColumnType("TEXT")
.HasMaxLength(100);
b.HasKey("Id");
b.HasIndex("CanonicalName")
.IsUnique();
b.HasIndex("CreatedById");
b.HasIndex("GroupId");
b.HasIndex("SystemIdentifier")
.IsUnique();
b.ToTable("Users");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.UserGroup", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(100);
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("Groups");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("ChatSettings")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings")
.WithMany("Channels")
.HasForeignKey("ChatSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Job", "Job")
.WithOne()
.HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("CompileJobs")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.ClientNoAction)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamDaemonSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamMakerSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("InstancePermissionSets")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.PermissionSet", "PermissionSet")
.WithMany("InstancePermissionSets")
.HasForeignKey("PermissionSetId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy")
.WithMany()
.HasForeignKey("CancelledById");
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("Jobs")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy")
.WithMany()
.HasForeignKey("StartedById")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "User")
.WithMany("OAuthConnections")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
{
b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
.WithOne("PermissionSet")
.HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "GroupId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Tgstation.Server.Host.Models.User", "User")
.WithOne("PermissionSet")
.HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob")
.WithMany()
.HasForeignKey("CompileJobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("RepositorySettings")
.HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("ActiveTestMerges")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge")
.WithMany("RevisonInformations")
.HasForeignKey("TestMergeId")
.OnDelete(DeleteBehavior.ClientNoAction)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("RevisionInformations")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy")
.WithMany("TestMerges")
.HasForeignKey("MergedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation")
.WithOne("PrimaryTestMerge")
.HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy")
.WithMany("CreatedUsers")
.HasForeignKey("CreatedById");
b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
.WithMany("Users")
.HasForeignKey("GroupId");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,117 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Tgstation.Server.Host.Database.Migrations
{
/// <summary>
/// Add DreamDaemon visibilty for SQLite.
/// </summary>
public partial class SLAddDreamDaemonVisibility : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
migrationBuilder.AddColumn<int>(
name: "LaunchVisibility",
table: "ReattachInformations",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "Visibility",
table: "DreamDaemonSettings",
nullable: false,
defaultValue: 0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
migrationBuilder.RenameTable(
name: "ReattachInformations",
newName: "ReattachInformations_down");
migrationBuilder.CreateTable(
name: "ReattachInformations",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
AccessIdentifier = table.Column<string>(nullable: false),
ProcessId = table.Column<int>(nullable: false),
Port = table.Column<ushort>(nullable: false),
RebootState = table.Column<int>(nullable: false),
LaunchSecurityLevel = table.Column<int>(nullable: false),
CompileJobId = table.Column<long>(nullable: false),
},
constraints: table =>
{
table.PrimaryKey("PK_ReattachInformations", x => x.Id);
table.ForeignKey(
name: "FK_ReattachInformations_CompileJobs_CompileJobId",
column: x => x.CompileJobId,
principalTable: "CompileJobs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.Sql(
$"INSERT INTO ReattachInformations SELECT Id,AccessIdentifier,ProcessId,Port,RebootState,LaunchSecurityLevel,CompileJobId FROM ReattachInformations_down");
migrationBuilder.DropTable(
name: "ReattachInformations_down");
migrationBuilder.RenameTable(
name: "ReattachInformations",
newName: "ReattachInformations_down");
migrationBuilder.RenameTable(
name: "ReattachInformations_down",
newName: "ReattachInformations");
migrationBuilder.RenameTable(
name: "DreamDaemonSettings",
newName: "DreamDaemonSettings_down");
migrationBuilder.CreateTable(
name: "DreamDaemonSettings",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
AllowWebClient = table.Column<bool>(nullable: false),
SecurityLevel = table.Column<int>(nullable: false),
Port = table.Column<ushort>(nullable: false),
StartupTimeout = table.Column<uint>(nullable: false),
HeartbeatSeconds = table.Column<uint>(nullable: false),
AutoStart = table.Column<bool>(nullable: false),
InstanceId = table.Column<long>(nullable: false),
TopicRequestTimeout = table.Column<uint>(nullable: false),
AdditionalParameters = table.Column<string>(maxLength: 10000, nullable: false),
},
constraints: table =>
{
table.PrimaryKey("PK_DreamDaemonSettings", x => x.Id);
table.ForeignKey(
name: "FK_DreamDaemonSettings_Instances_InstanceId",
column: x => x.InstanceId,
principalTable: "Instances",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.Sql(
$"INSERT INTO DreamDaemonSettings SELECT Id,AllowWebClient,SecurityLevel,Port,AutoStart,HeartbeatSeconds,StartupTimeout,InstanceId,TopicRequestTimeout,AdditionalParameters FROM DreamDaemonSettings_down");
migrationBuilder.DropTable(
name: "DreamDaemonSettings_down");
}
}
}
@@ -1,4 +1,4 @@
// <auto-generated />
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@@ -8,12 +8,11 @@ namespace Tgstation.Server.Host.Database.Migrations
[DbContext(typeof(MySqlDatabaseContext))]
partial class MySqlDatabaseContextModelSnapshot : ModelSnapshot
{
/// <inheritdoc />
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.10")
.HasAnnotation("ProductVersion", "3.1.18")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
@@ -202,6 +201,9 @@ namespace Tgstation.Server.Host.Database.Migrations
.IsRequired()
.HasColumnType("int unsigned");
b.Property<int>("Visibility")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("InstanceId")
@@ -451,6 +453,9 @@ namespace Tgstation.Server.Host.Database.Migrations
b.Property<int>("LaunchSecurityLevel")
.HasColumnType("int");
b.Property<int>("LaunchVisibility")
.HasColumnType("int");
b.Property<ushort>("Port")
.HasColumnType("smallint unsigned");
@@ -1,4 +1,4 @@
// <auto-generated />
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@@ -9,13 +9,12 @@ namespace Tgstation.Server.Host.Database.Migrations
[DbContext(typeof(PostgresSqlDatabaseContext))]
partial class PostgresSqlDatabaseContextModelSnapshot : ModelSnapshot
{
/// <inheritdoc />
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "3.1.10")
.HasAnnotation("ProductVersion", "3.1.18")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
@@ -202,6 +201,9 @@ namespace Tgstation.Server.Host.Database.Migrations
b.Property<long>("TopicRequestTimeout")
.HasColumnType("bigint");
b.Property<int>("Visibility")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("InstanceId")
@@ -455,6 +457,9 @@ namespace Tgstation.Server.Host.Database.Migrations
b.Property<int>("LaunchSecurityLevel")
.HasColumnType("integer");
b.Property<int>("LaunchVisibility")
.HasColumnType("integer");
b.Property<int>("Port")
.HasColumnType("integer");
@@ -1,4 +1,4 @@
// <auto-generated />
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@@ -9,12 +9,11 @@ namespace Tgstation.Server.Host.Database.Migrations
[DbContext(typeof(SqlServerDatabaseContext))]
partial class SqlServerDatabaseContextModelSnapshot : ModelSnapshot
{
/// <inheritdoc />
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.10")
.HasAnnotation("ProductVersion", "3.1.18")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
@@ -204,6 +203,9 @@ namespace Tgstation.Server.Host.Database.Migrations
b.Property<long>("TopicRequestTimeout")
.HasColumnType("bigint");
b.Property<int>("Visibility")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("InstanceId")
@@ -460,6 +462,9 @@ namespace Tgstation.Server.Host.Database.Migrations
b.Property<int>("LaunchSecurityLevel")
.HasColumnType("int");
b.Property<int>("LaunchVisibility")
.HasColumnType("int");
b.Property<int>("Port")
.HasColumnType("int");
@@ -1,4 +1,4 @@
// <auto-generated />
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@@ -8,16 +8,15 @@ namespace Tgstation.Server.Host.Database.Migrations
[DbContext(typeof(SqliteDatabaseContext))]
partial class SqliteDatabaseContextModelSnapshot : ModelSnapshot
{
/// <inheritdoc />
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.10");
.HasAnnotation("ProductVersion", "3.1.18");
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.Property<long>("Id")
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
@@ -101,7 +100,7 @@ namespace Tgstation.Server.Host.Database.Migrations
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.Property<long>("Id")
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
@@ -201,6 +200,9 @@ namespace Tgstation.Server.Host.Database.Migrations
.IsRequired()
.HasColumnType("INTEGER");
b.Property<int>("Visibility")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("InstanceId")
@@ -243,7 +245,7 @@ namespace Tgstation.Server.Host.Database.Migrations
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
{
b.Property<long>("Id")
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
@@ -261,7 +263,7 @@ namespace Tgstation.Server.Host.Database.Migrations
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(10000);
.HasMaxLength(100);
b.Property<bool?>("Online")
.IsRequired()
@@ -327,7 +329,7 @@ namespace Tgstation.Server.Host.Database.Migrations
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.Property<long>("Id")
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
@@ -450,6 +452,9 @@ namespace Tgstation.Server.Host.Database.Migrations
b.Property<int>("LaunchSecurityLevel")
.HasColumnType("INTEGER");
b.Property<int>("LaunchVisibility")
.HasColumnType("INTEGER");
b.Property<ushort>("Port")
.HasColumnType("INTEGER");
@@ -687,7 +692,7 @@ namespace Tgstation.Server.Host.Database.Migrations
modelBuilder.Entity("Tgstation.Server.Host.Models.UserGroup", b =>
{
b.Property<long>("Id")
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
@@ -34,6 +34,12 @@ namespace Tgstation.Server.Host.Models
[Required]
public DreamDaemonSecurity? LaunchSecurityLevel { get; set; }
/// <summary>
/// The <see cref="DreamDaemonVisibility"/> DreamDaemon was launched with.
/// </summary>
[Required]
public DreamDaemonVisibility? LaunchVisibility { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ReattachInformationBase"/> class.
/// </summary>
@@ -54,6 +60,7 @@ namespace Tgstation.Server.Host.Models
ProcessId = copy.ProcessId;
RebootState = copy.RebootState;
LaunchSecurityLevel = copy.LaunchSecurityLevel;
LaunchVisibility = copy.LaunchVisibility;
}
/// <inheritdoc />
@@ -1,10 +1,11 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Models.Request;
using Tgstation.Server.Api.Rights;
using Tgstation.Server.Client;
using Tgstation.Server.Client.Components;
using Tgstation.Server.Host.System;
@@ -15,15 +16,18 @@ namespace Tgstation.Server.Tests.Instance
{
readonly IDreamMakerClient dreamMakerClient;
readonly IDreamDaemonClient dreamDaemonClient;
readonly IInstanceClient instanceClient;
public DeploymentTest(IDreamMakerClient dreamMakerClient, IDreamDaemonClient dreamDaemonClient, IJobsClient jobsClient) : base(jobsClient)
public DeploymentTest(IInstanceClient instanceClient, IJobsClient jobsClient) : base(jobsClient)
{
this.dreamMakerClient = dreamMakerClient ?? throw new ArgumentNullException(nameof(dreamMakerClient));
this.dreamDaemonClient = dreamDaemonClient ?? throw new ArgumentNullException(nameof(dreamDaemonClient));
this.instanceClient = instanceClient ?? throw new ArgumentException(nameof(instanceClient));
this.dreamMakerClient = instanceClient.DreamMaker;
this.dreamDaemonClient = instanceClient.DreamDaemon;
}
public async Task Run(Task repositoryTask, CancellationToken cancellationToken)
{
var vpTest = TestVisibilityPermission(cancellationToken);
var deployJob = await dreamMakerClient.Compile(cancellationToken);
deployJob = await WaitForJob(deployJob, 30, true, null, cancellationToken);
Assert.IsTrue(deployJob.ErrorCode == ErrorCode.RepoCloning || deployJob.ErrorCode == ErrorCode.RepoMissing);
@@ -93,6 +97,47 @@ namespace Tgstation.Server.Tests.Instance
deployJob = await dreamMakerClient.Compile(cancellationToken);
await WaitForJob(deployJob, 30, true, ErrorCode.DreamMakerMissingDme, cancellationToken);
// check that we can change the visibility
await vpTest;
}
async Task TestVisibilityPermission(CancellationToken cancellationToken)
{
var updatedDD = await dreamDaemonClient.Read(cancellationToken);
Assert.AreEqual(DreamDaemonVisibility.Public, updatedDD.Visibility);
updatedDD = await dreamDaemonClient.Update(new DreamDaemonRequest
{
Visibility = DreamDaemonVisibility.Invisible
}, cancellationToken);
Assert.AreEqual(DreamDaemonVisibility.Invisible, updatedDD.Visibility);
var currentPermissionSet = await instanceClient.PermissionSets.Read(cancellationToken);
Assert.IsTrue((currentPermissionSet.DreamDaemonRights.Value & DreamDaemonRights.SetVisibility) != 0);
var updatedPS = await instanceClient.PermissionSets.Update(new InstancePermissionSetRequest
{
PermissionSetId = currentPermissionSet.PermissionSetId,
DreamDaemonRights = currentPermissionSet.DreamDaemonRights.Value & ~DreamDaemonRights.SetVisibility
}, cancellationToken);
Assert.IsFalse((updatedPS.DreamDaemonRights.Value & DreamDaemonRights.SetVisibility) != 0);
await ApiAssert.ThrowsException<InsufficientPermissionsException>(() => dreamDaemonClient.Update(new DreamDaemonRequest
{
Visibility = DreamDaemonVisibility.Private
}, cancellationToken), null);
updatedPS = await instanceClient.PermissionSets.Update(new InstancePermissionSetRequest
{
PermissionSetId = updatedPS.PermissionSetId,
DreamDaemonRights = updatedPS.DreamDaemonRights.Value | DreamDaemonRights.SetVisibility
}, cancellationToken);
Assert.IsTrue((updatedPS.DreamDaemonRights.Value & DreamDaemonRights.SetVisibility) != 0);
updatedDD = await dreamDaemonClient.Update(new DreamDaemonRequest
{
Visibility = DreamDaemonVisibility.Public
}, cancellationToken);
Assert.AreEqual(DreamDaemonVisibility.Public, updatedDD.Visibility);
}
}
}
@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
@@ -24,7 +24,7 @@ namespace Tgstation.Server.Tests.Instance
var chatTest = new ChatTest(instanceClient.ChatBots, instanceManagerClient, instanceClient.Metadata);
var configTest = new ConfigurationTest(instanceClient.Configuration, instanceClient.Metadata);
var repoTest = new RepositoryTest(instanceClient.Repository, instanceClient.Jobs);
var dmTest = new DeploymentTest(instanceClient.DreamMaker, instanceClient.DreamDaemon, instanceClient.Jobs);
var dmTest = new DeploymentTest(instanceClient, instanceClient.Jobs);
var byondTests = byondTest.Run(cancellationToken);
var repoTests = repoTest.RunPreWatchdog(cancellationToken);
@@ -739,6 +739,7 @@ namespace Tgstation.Server.Tests
HeartbeatSeconds = 0,
Port = 1447,
SecurityLevel = DreamDaemonSecurity.Safe,
Visibility = DreamDaemonVisibility.Public,
StartupTimeout = 1000,
TopicRequestTimeout = 1000,
AdditionalParameters = String.Empty,