Seenginx/Seenginx/Services/NginxService.cs

349 lines
11 KiB
C#

using Microsoft.CodeAnalysis;
using Seenginx.Models;
using Seenginx.Services.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
namespace Seenginx.Services
{
public class NginxService : INginxService
{
private readonly SeenginxSettings Settings;
private readonly CommandService CommandService;
public NginxService(SeenginxSettings configPaths, CommandService commandService)
{
Settings = configPaths;
CommandService = commandService;
}
public async Task<IEnumerable<ConfigFile>> GetFilesAsync()
{
await Task.Run(() => { });
var rootConfigs = Directory.GetFiles(Settings.nginx.rootPath, "*.conf");
var rootDraftConfigs = Directory.GetFiles(Settings.nginx.rootPath, "*.conf.draft");
var confdConfigs = Directory.GetFiles(Path.Combine(Settings.nginx.rootPath, "conf.d"), "*.conf");
var confDraftConfigs = Directory.GetFiles(Path.Combine(Settings.nginx.rootPath, "conf.d"), "*.conf.draft");
var sitesAvailableConfigs = Directory.GetFiles(Path.Combine(Settings.nginx.rootPath, "sites-available"), "*.conf");
var sitesAvailableDraftConfigs = Directory.GetFiles(Path.Combine(Settings.nginx.rootPath, "sites-available"), "*.conf.draft");
var rootConfigFiles = rootConfigs.Select(fp =>
{
var name = Path.GetFileNameWithoutExtension(fp);
var configFile = new ConfigFile();
configFile.CanBeDeleted = false;
configFile.Folder = string.Empty;
configFile.LastUpdated = File.GetLastWriteTime(fp);
configFile.Name = name;
configFile.FullPath = Path.Combine(Settings.nginx.rootPath, $"{configFile.Name}.conf");
configFile.Body = File.ReadAllText(fp);
if (rootDraftConfigs.Any(cfp => cfp.Contains(name)))
configFile.DraftBody = File.ReadAllText(rootDraftConfigs.First(cfp => cfp.Contains(name)));
return configFile;
});
var confdConfigFiles = confdConfigs.Select(fp =>
{
var fileName = Path.GetFileNameWithoutExtension(fp);
var configFile = new ConfigFile();
configFile.CanBeDeleted = true;
configFile.Folder = "conf.d";
configFile.LastUpdated = File.GetLastWriteTime(fp);
configFile.Name = fileName;
configFile.FullPath = Path.Combine(Settings.nginx.rootPath, configFile.Folder, $"{configFile.Name}.conf");
configFile.Body = File.ReadAllText(fp);
if (confDraftConfigs.Any(cfp => cfp.Contains(fileName)))
configFile.DraftBody = File.ReadAllText(confDraftConfigs.First(cfp => cfp.Contains(fileName)));
return configFile;
});
var sitesAvailableConfigFiles = sitesAvailableConfigs.Select(fp =>
{
var fileName = Path.GetFileNameWithoutExtension(fp);
var configFile = new ConfigFile();
configFile.CanBeDeleted = true;
configFile.Folder = "sites-available";
configFile.LastUpdated = File.GetLastWriteTime(fp);
configFile.Name = fileName;
configFile.FullPath = Path.Combine(Settings.nginx.rootPath, configFile.Folder, $"{configFile.Name}.conf");
configFile.Body = File.ReadAllText(fp);
if (sitesAvailableDraftConfigs.Any(cfp => cfp.Contains(fileName)))
configFile.DraftBody = File.ReadAllText(sitesAvailableDraftConfigs.First(cfp => cfp.Contains(fileName)));
return configFile;
});
var finalList = new List<ConfigFile>();
finalList.AddRange(rootConfigFiles);
finalList.AddRange(confdConfigFiles);
finalList.AddRange(sitesAvailableConfigFiles);
finalList = finalList.OrderBy(cf => cf.Name).ToList();
return finalList;
}
public async Task<IEnumerable<Template>> GetTemplates()
{
var templates = new List<Template>();
try
{
var nginxTemplateDirectory = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "templates", "nginx");
var nginxTemplateFiles = Directory.GetFiles(nginxTemplateDirectory, "*.template");
foreach (var templateFilePath in nginxTemplateFiles)
{
var template = new Template();
var templateFileLines = await File.ReadAllLinesAsync(templateFilePath);
template.Name = templateFileLines.FirstOrDefault();
template.Code = string.Join(Environment.NewLine, templateFileLines.Skip(2));
templates.Add(template);
}
return templates;
}
catch (Exception ex)
{
throw ex;
}
}
public async Task<Result> ValidateForAddFileAsync(NewFileForm newFileForm)
{
var validationResult = new Result();
try
{
var filePath = Path.Combine(Settings.nginx.rootPath, "conf.d", $"{newFileForm.Name}.conf");
if (File.Exists(filePath))
return validationResult.Invalidate($"There's already a file with the '{newFileForm.Name}.conf' name.");
return validationResult;
}
catch (Exception ex)
{
return validationResult.Invalidate($"Exception at {nameof(ValidateForAddFileAsync)}()", ex);
}
}
public async Task<Result<ConfigFile>> AddFileAsync(NewFileForm newFileForm)
{
var addResult = new Result<ConfigFile>();
try
{
var newFile = new ConfigFile();
newFile.Name = newFileForm.Name;
newFile.Folder = "conf.d";
newFile.FullPath = Path.Combine(Settings.nginx.rootPath, newFile.Folder, $"{newFileForm.Name}.conf");
newFile.Body = newFileForm.SelectedTemplate == 0.ToString() ? string.Empty : (await GetTemplates()).SingleOrDefault(t => t.Name == newFileForm.SelectedTemplate)?.Code;
newFile.LastUpdated = DateTime.UtcNow;
await File.WriteAllTextAsync(newFile.FullPath, newFile.Body, Encoding.UTF8);
addResult.SetData(newFile);
return addResult;
}
catch (Exception ex)
{
return addResult.Invalidate(ex.Message, ex);
}
}
public async Task<Result> ValidateForDeleteFileAsync(ConfigFile configFile)
{
var validationResult = new Result();
try
{
if (File.Exists(configFile.FullPath))
return validationResult.Invalidate($"File '{configFile.FullPath}' not found.");
return validationResult;
}
catch (Exception ex)
{
return validationResult.Invalidate(ex.Message, ex);
}
}
public async Task<Result> DeleteFileAsync(ConfigFile configFile)
{
var result = new Result();
try
{
if (!File.Exists(configFile.FullPath))
return result.Invalidate($"File '{configFile.FullPath}' not found.");
File.Delete(configFile.FullPath);
if (configFile.DraftBody != null)
File.Delete($"{configFile.FullPath}.draft");
return result;
}
catch (Exception ex)
{
return result.Invalidate(ex.Message, ex);
}
}
public async Task<Result> ValidateForSaveFileAsync(ConfigFile configFile)
{
var validationResult = new Result();
try
{
if (File.Exists(configFile.FullPath))
return validationResult.Invalidate($"File '{configFile.FullPath}' not found.");
return validationResult;
}
catch (Exception ex)
{
return validationResult.Invalidate(ex.Message, ex);
}
}
public async Task<Result<ConfigFile>> SaveFileAsync(ConfigFile configFile)
{
var saveResult = new Result<ConfigFile>();
try
{
await File.WriteAllTextAsync(Path.Combine(Settings.nginx.rootPath, configFile.Folder, $"{configFile.Name}.conf"), configFile.Body, Encoding.UTF8);
return saveResult;
}
catch (Exception ex)
{
return saveResult.Invalidate(ex.Message, ex);
}
}
public async Task<Result> ValidateForSaveDraftFileAsync(ConfigFile configFile)
{
var validationResult = new Result();
try
{
var draftPathName = $"{configFile.FullPath}.draft";
if (!File.Exists(draftPathName))
return validationResult.Invalidate($"File '{draftPathName}' not found.");
return validationResult;
}
catch (Exception ex)
{
return validationResult.Invalidate(ex.Message, ex);
}
}
public async Task<Result<ConfigFile>> SaveDraftFileAsync(ConfigFile configFile)
{
var saveDraftResult = new Result<ConfigFile>();
try
{
await File.WriteAllTextAsync(Path.Combine(Settings.nginx.rootPath, configFile.Folder, $"{configFile.Name}.conf.draft"), configFile.DraftBody, Encoding.UTF8);
return saveDraftResult;
}
catch (Exception ex)
{
return saveDraftResult.Invalidate(ex.Message, ex);
}
}
public async Task<Result> ValidateForRenameFileAsync(List<ConfigFile> configFiles, ConfigFile selectedConfigFile, string newName)
{
var renameResult = new Result();
try
{
if (configFiles.Count(cf => cf.Name == newName) > 0)
return renameResult.Invalidate($"File '{selectedConfigFile.FullPath}' already exists.");
if (!File.Exists(selectedConfigFile.FullPath))
return renameResult.Invalidate($"Original file '{selectedConfigFile.FullPath}' not found.");
var newPathName = Path.Combine(Settings.nginx.rootPath, selectedConfigFile.Folder, $"{newName}.conf");
if (File.Exists(newPathName))
return renameResult.Invalidate($"The file '{newPathName}' already exists.");
return renameResult;
}
catch (Exception ex)
{
return renameResult.Invalidate(ex.Message, ex);
}
}
public async Task<Result<ConfigFile>> RenameFileAsync(ConfigFile configFile, string newName)
{
var renameResult = new Result<ConfigFile>();
try
{
var originalPathName = Path.Combine(Settings.nginx.rootPath, configFile.Folder, $"{configFile.Name}.conf");
var newPathName = Path.Combine(Settings.nginx.rootPath, configFile.Folder, newName);
File.Move(originalPathName, newPathName, overwrite: false);
if (configFile.DraftBody != null)
File.Move($"{originalPathName}.draft", $"{newPathName}.draft", overwrite: false);
configFile.FullPath = newPathName;
renameResult.SetData(configFile);
return renameResult;
}
catch (Exception ex)
{
return renameResult.Invalidate(ex.Message, ex);
}
}
public async Task<Result<string>> TestFileAsync(ConfigFile configFile)
{
var command1 = string.Empty;
var command2 = string.Empty;
var runResult = new Result<string>();
var originalPathName = Path.Combine(Settings.nginx.rootPath, configFile.Folder, $"{configFile.Name}.conf");
switch (Environment.OSVersion.Platform)
{
case PlatformID.Win32S:
case PlatformID.Win32Windows:
case PlatformID.Win32NT:
case PlatformID.WinCE:
//command1 = @$"cd ""C:\Program Files\nginx""";
command2 = @$"nginx.exe -c ""{originalPathName}"" -t";
break;
case PlatformID.Unix:
command1 = "";
break;
case PlatformID.Xbox:
case PlatformID.MacOSX:
return runResult.Invalidate($"Invalid platform '{Environment.OSVersion.Platform}'");
}
runResult = await CommandService.RunCommandAsync(/*command1,*/ command2);
return runResult;
}
}
}