/// <summary> /// Implementation of <see cref="Read(CancellationToken)"/> /// </summary> /// <param name="settings">The <see cref="DreamDaemonSettings"/> to operate on if any</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param> /// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> of the operation</returns> async Task <IActionResult> ReadImpl(DreamDaemonSettings settings, CancellationToken cancellationToken) { var instance = instanceManager.GetInstance(Instance); var dd = instance.Watchdog; var metadata = (AuthenticationContext.GetRight(RightsType.DreamDaemon) & (ulong)DreamDaemonRights.ReadMetadata) != 0; var revision = (AuthenticationContext.GetRight(RightsType.DreamDaemon) & (ulong)DreamDaemonRights.ReadRevision) != 0; if (settings == null) { settings = await DatabaseContext .Instances .AsQueryable() .Where(x => x.Id == Instance.Id) .Select(x => x.DreamDaemonSettings) .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); if (settings == default) { return(StatusCode((int)HttpStatusCode.Gone)); } } var result = new DreamDaemon(); if (metadata) { var alphaActive = dd.AlphaIsActive; var llp = dd.LastLaunchParameters; var rstate = dd.RebootState; result.AutoStart = settings.AutoStart.Value; result.CurrentPort = alphaActive ? llp?.PrimaryPort.Value : llp?.SecondaryPort.Value; result.CurrentSecurity = llp?.SecurityLevel.Value; result.CurrentAllowWebclient = llp?.AllowWebClient.Value; result.PrimaryPort = settings.PrimaryPort.Value; result.AllowWebClient = settings.AllowWebClient.Value; result.Running = dd.Running; result.SecondaryPort = settings.SecondaryPort.Value; result.SecurityLevel = settings.SecurityLevel.Value; result.SoftRestart = rstate == RebootState.Restart; result.SoftShutdown = rstate == RebootState.Shutdown; result.StartupTimeout = settings.StartupTimeout.Value; result.HeartbeatSeconds = settings.HeartbeatSeconds.Value; } if (revision) { var latestCompileJob = instance.LatestCompileJob(); result.ActiveCompileJob = ((dd.Running ? dd.ActiveCompileJob : latestCompileJob) ?? latestCompileJob)?.ToApi(); if (latestCompileJob?.Id != result.ActiveCompileJob?.Id) { result.StagedCompileJob = latestCompileJob?.ToApi(); } } return(Json(result)); }
/// <inheritdoc /> public Task <DreamDaemon> Update(DreamDaemon dreamDaemon, CancellationToken cancellationToken) => apiClient.Update <DreamDaemon, DreamDaemon>(Routes.DreamDaemon, dreamDaemon, instance.Id, cancellationToken);
#pragma warning disable CA1506 // TODO: Decomplexify public async Task <IActionResult> Update([FromBody] DreamDaemon model, CancellationToken cancellationToken) { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (model.PrimaryPort == 0) { return(BadRequest(new ErrorMessage { Message = "Primary port cannot be 0!" })); } if (model.SecurityLevel == DreamDaemonSecurity.Ultrasafe) { return(BadRequest(new ErrorMessage { Message = "This version of TGS does not support the ultrasafe DreamDaemon configuration!" })); } // alias for changing DD settings var current = await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).Select(x => x.DreamDaemonSettings).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); if (current == default) { return(StatusCode((int)HttpStatusCode.Gone)); } var userRights = (DreamDaemonRights)AuthenticationContext.GetRight(RightsType.DreamDaemon); bool CheckModified <T>(Expression <Func <Api.Models.Internal.DreamDaemonSettings, T> > expression, DreamDaemonRights requiredRight) { var memberSelectorExpression = (MemberExpression)expression.Body; var property = (PropertyInfo)memberSelectorExpression.Member; var newVal = property.GetValue(model); if (newVal == null) { return(false); } if (!userRights.HasFlag(requiredRight) && property.GetValue(current) != newVal) { return(true); } property.SetValue(current, newVal); return(false); } var oldSoftRestart = current.SoftRestart; var oldSoftShutdown = current.SoftShutdown; if (CheckModified(x => x.AllowWebClient, DreamDaemonRights.SetWebClient) || CheckModified(x => x.AutoStart, DreamDaemonRights.SetAutoStart) || CheckModified(x => x.PrimaryPort, DreamDaemonRights.SetPorts) || CheckModified(x => x.SecondaryPort, DreamDaemonRights.SetPorts) || CheckModified(x => x.SecurityLevel, DreamDaemonRights.SetSecurity) || CheckModified(x => x.SoftRestart, DreamDaemonRights.SoftRestart) || CheckModified(x => x.SoftShutdown, DreamDaemonRights.SoftShutdown) || CheckModified(x => x.StartupTimeout, DreamDaemonRights.SetStartupTimeout)) { return(Forbid()); } if (current.PrimaryPort == current.SecondaryPort) { return(BadRequest(new ErrorMessage { Message = "Primary port and secondary port cannot be the same!" })); } var wd = instanceManager.GetInstance(Instance).Watchdog; await DatabaseContext.Save(cancellationToken).ConfigureAwait(false); // run this second because current may be modified by it await wd.ChangeSettings(current, cancellationToken).ConfigureAwait(false); if (!oldSoftRestart.Value && current.SoftRestart.Value) { await wd.Restart(true, cancellationToken).ConfigureAwait(false); } else if (!oldSoftShutdown.Value && current.SoftShutdown.Value) { await wd.Terminate(true, cancellationToken).ConfigureAwait(false); } else if ((oldSoftRestart.Value && !current.SoftRestart.Value) || (oldSoftShutdown.Value && !current.SoftShutdown.Value)) { await wd.ResetRebootState(cancellationToken).ConfigureAwait(false); } return(await ReadImpl(current, cancellationToken).ConfigureAwait(false)); }
/// <inheritdoc /> public Task <DreamDaemon> Update(DreamDaemon dreamDaemon, CancellationToken cancellationToken) => apiClient.Update <DreamDaemon, DreamDaemon>(Routes.DreamDaemon, dreamDaemon ?? throw new ArgumentNullException(nameof(dreamDaemon)), instance.Id, cancellationToken);