diff --git a/Moonlight/App/ApiClients/CloudPanel/Requests/AddDatabase.cs b/Moonlight/App/ApiClients/CloudPanel/Requests/AddDatabase.cs new file mode 100644 index 00000000..26d8d4bb --- /dev/null +++ b/Moonlight/App/ApiClients/CloudPanel/Requests/AddDatabase.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; + +namespace Moonlight.App.ApiClients.CloudPanel.Requests; + +public class AddDatabase +{ + [JsonProperty("domainName")] + public string DomainName { get; set; } + + [JsonProperty("databaseName")] + public string DatabaseName { get; set; } + + [JsonProperty("databaseUserName")] + public string DatabaseUserName { get; set; } + + [JsonProperty("databaseUserPassword")] + public string DatabaseUserPassword { get; set; } +} \ No newline at end of file diff --git a/Moonlight/App/ApiClients/CloudPanel/Requests/InstallLetsEncrypt.cs b/Moonlight/App/ApiClients/CloudPanel/Requests/InstallLetsEncrypt.cs new file mode 100644 index 00000000..e10068fd --- /dev/null +++ b/Moonlight/App/ApiClients/CloudPanel/Requests/InstallLetsEncrypt.cs @@ -0,0 +1,9 @@ +using Newtonsoft.Json; + +namespace Moonlight.App.ApiClients.CloudPanel.Requests; + +public class InstallLetsEncrypt +{ + [JsonProperty("domainName")] + public string DomainName { get; set; } +} \ No newline at end of file diff --git a/Moonlight/App/Models/Forms/DomainOrderDataModel.cs b/Moonlight/App/Models/Forms/DomainOrderDataModel.cs index c49dd8e3..b3b8a93f 100644 --- a/Moonlight/App/Models/Forms/DomainOrderDataModel.cs +++ b/Moonlight/App/Models/Forms/DomainOrderDataModel.cs @@ -7,7 +7,7 @@ public class DomainOrderDataModel { [Required(ErrorMessage = "You need to specify a name")] [MaxLength(32, ErrorMessage = "The max lenght for the name is 32 characters")] - [RegularExpression(@"^[a-z]+$", ErrorMessage = "The name should only consist of lower case characters")] + [RegularExpression(@"^[a-z0-9]+$", ErrorMessage = "The name should only consist of lower case characters or numbers")] public string Name { get; set; } = ""; [Required(ErrorMessage = "You need to specify a shared domain")] diff --git a/Moonlight/App/Services/SmartDeployService.cs b/Moonlight/App/Services/SmartDeployService.cs index e5e69f87..38d013a0 100644 --- a/Moonlight/App/Services/SmartDeployService.cs +++ b/Moonlight/App/Services/SmartDeployService.cs @@ -6,18 +6,20 @@ namespace Moonlight.App.Services; public class SmartDeployService { private readonly NodeRepository NodeRepository; - private readonly PleskServerRepository PleskServerRepository; + private readonly Repository CloudPanelRepository; private readonly WebSpaceService WebSpaceService; private readonly NodeService NodeService; public SmartDeployService( NodeRepository nodeRepository, - NodeService nodeService, PleskServerRepository pleskServerRepository, WebSpaceService webSpaceService) + NodeService nodeService, + WebSpaceService webSpaceService, + Repository cloudPanelRepository) { NodeRepository = nodeRepository; NodeService = nodeService; - PleskServerRepository = pleskServerRepository; WebSpaceService = webSpaceService; + CloudPanelRepository = cloudPanelRepository; } public async Task GetNode() @@ -38,13 +40,14 @@ public class SmartDeployService return data.MaxBy(x => x.Value).Key; } - public async Task GetPleskServer() + public async Task GetCloudPanel() { - var result = new List(); + var result = new List(); - foreach (var pleskServer in PleskServerRepository.Get().ToArray()) + foreach (var cloudPanel in CloudPanelRepository.Get().ToArray()) { - result.Add(pleskServer); + if (await WebSpaceService.IsHostUp(cloudPanel)) + result.Add(cloudPanel); } return result.FirstOrDefault(); diff --git a/Moonlight/App/Services/WebSpaceService.cs b/Moonlight/App/Services/WebSpaceService.cs index 549c44dc..91a3d718 100644 --- a/Moonlight/App/Services/WebSpaceService.cs +++ b/Moonlight/App/Services/WebSpaceService.cs @@ -17,13 +17,16 @@ public class WebSpaceService { private readonly Repository CloudPanelRepository; private readonly Repository WebSpaceRepository; + private readonly Repository DatabaseRepository; + private readonly CloudPanelApiHelper CloudPanelApiHelper; - public WebSpaceService(Repository cloudPanelRepository, Repository webSpaceRepository, CloudPanelApiHelper cloudPanelApiHelper) + public WebSpaceService(Repository cloudPanelRepository, Repository webSpaceRepository, CloudPanelApiHelper cloudPanelApiHelper, Repository databaseRepository) { CloudPanelRepository = cloudPanelRepository; WebSpaceRepository = webSpaceRepository; CloudPanelApiHelper = cloudPanelApiHelper; + DatabaseRepository = databaseRepository; } public async Task Create(string domain, User owner, CloudPanel? ps = null) @@ -83,14 +86,16 @@ public class WebSpaceService { try { - //var res = await PleskApiHelper.Get(pleskServer, "server"); + await CloudPanelApiHelper.Post(cloudPanel, "", null); return true; - - //if (res != null) - // return true; } - catch (Exception e) + catch (CloudPanelException e) + { + if (e.StatusCode == 404) + return true; + } + catch (Exception) { // ignored } @@ -105,40 +110,60 @@ public class WebSpaceService return await IsHostUp(webSpace.CloudPanel); } - #region SSL - public async Task GetSslCertificates(WebSpace w) + public async Task IssueSslCertificate(WebSpace w) { - var certs = new List(); - return certs.ToArray(); - } + var webspace = EnsureData(w); - public async Task CreateSslCertificate(WebSpace w) - { - + await CloudPanelApiHelper.Post(webspace.CloudPanel, "letsencrypt/install/certificate", new InstallLetsEncrypt() + { + DomainName = webspace.Domain + }); } - public async Task DeleteSslCertificate(WebSpace w, string name) - { - - } - - #endregion - #region Databases - public async Task GetDatabases(WebSpace w) + public Task GetDatabases(WebSpace w) { - return Array.Empty(); + return Task.FromResult(WebSpaceRepository + .Get() + .Include(x => x.Databases) + .First(x => x.Id == w.Id) + .Databases.ToArray()); } public async Task CreateDatabase(WebSpace w, string name, string password) { + if (DatabaseRepository.Get().Any(x => x.UserName == name)) + throw new DisplayException("A database with this name does already exist"); + + var webspace = EnsureData(w); + + var database = new MySqlDatabase() + { + UserName = name, + Password = password + }; + + await CloudPanelApiHelper.Post(webspace.CloudPanel, "db", new AddDatabase() + { + DomainName = webspace.Domain, + DatabaseName = database.UserName, + DatabaseUserName = database.UserName, + DatabaseUserPassword = database.Password + }); + webspace.Databases.Add(database); + WebSpaceRepository.Update(webspace); } - public async Task DeleteDatabase(WebSpace w, Models.Plesk.Resources.Database database) + public async Task DeleteDatabase(WebSpace w, MySqlDatabase database) { + var webspace = EnsureData(w); + await CloudPanelApiHelper.Delete(webspace.CloudPanel, $"db/{database.UserName}", null); + + webspace.Databases.Remove(database); + WebSpaceRepository.Update(webspace); } #endregion diff --git a/Moonlight/Shared/Components/Partials/Navbar.razor b/Moonlight/Shared/Components/Partials/Navbar.razor index f0f01e56..79fe3f9d 100644 --- a/Moonlight/Shared/Components/Partials/Navbar.razor +++ b/Moonlight/Shared/Components/Partials/Navbar.razor @@ -9,33 +9,36 @@ @inject NavigationManager NavigationManager @inject CookieService CookieService -