Skip to content

Commit

Permalink
#115 refactor: improved configuration hierarchy
Browse files Browse the repository at this point in the history
+ Generalized clone method for Configuration
  • Loading branch information
joseantmazonsb committed Feb 27, 2022
1 parent 01e3ec1 commit 8af502d
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 81 deletions.
13 changes: 8 additions & 5 deletions Linguard/Core/Configuration/Configuration.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
namespace Linguard.Core.Configuration;

public class Configuration : IConfiguration {

public IWireguardConfiguration Wireguard { get; set; } = new WireguardConfiguration();
public ILoggingConfiguration Logging { get; set; } = new LoggingConfiguration();
public IWebConfiguration Web { get; set; } = new WebConfiguration();
public ITrafficConfiguration Traffic { get; set; } = new TrafficConfiguration();

public object Clone() {
var clone = (IConfiguration) MemberwiseClone();
clone.Wireguard = (IWireguardConfiguration) Wireguard.Clone();
clone.Logging = (ILoggingConfiguration) Logging.Clone();
clone.Web = (IWebConfiguration) Web.Clone();
clone.Traffic = (ITrafficConfiguration) Traffic.Clone();
var cloneableProperties = GetType().GetProperties()
.Where(p => p.PropertyType.GetInterfaces().Contains(typeof(ICloneable)));
foreach (var property in cloneableProperties) {
var propertyValue = property.GetValue(this);
var propertyClone = propertyValue?.GetType().GetMethod(nameof(Clone))
!.Invoke(propertyValue, Array.Empty<object>());
property.SetValue(clone, propertyClone);
}
return clone;
}
}
65 changes: 65 additions & 0 deletions Linguard/Core/Managers/ConfigurationManagerBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Linguard.Core.Configuration;
using Linguard.Core.Drivers.TrafficStorage;
using Linguard.Core.Models;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Linguard.Core.Utils;
using Linguard.Log;

namespace Linguard.Core.Managers;

public abstract class ConfigurationManagerBase : IConfigurationManager {

private readonly ICommandRunner _commandRunner;

protected ConfigurationManagerBase(IConfiguration configuration, IWorkingDirectory workingDirectory,
ICommandRunner commandRunner) {
Configuration = configuration;
WorkingDirectory = workingDirectory;
_commandRunner = commandRunner;
}

public IConfiguration Configuration { get; set; }
public IWorkingDirectory WorkingDirectory { get; set; }

public void LoadDefaults() {
LoadWebDefaults();
LoadLoggingDefaults();
LoadTrafficDefaults();
LoadWireguardDefaults();
}

private void LoadWebDefaults() {
Configuration.Web.Style = Style.Default;
Configuration.Web.LoginAttempts = 10;
Configuration.Web.SecretKey = "";
}
private void LoadLoggingDefaults() {
Configuration.Logging.Level = LogLevel.Info;
Configuration.Logging.Overwrite = false;
}
private void LoadTrafficDefaults() {
Configuration.Traffic.Enabled = true;
Configuration.Traffic.StorageDriver = new JsonTrafficStorageDriver();
}
private void LoadWireguardDefaults() {
Configuration.Wireguard.Interfaces = new HashSet<Interface>();
Configuration.Wireguard.IptablesBin = _commandRunner
.Run("whereis iptables | tr ' ' '\n' | grep bin").Stdout;
Configuration.Wireguard.WireguardBin = _commandRunner
.Run("whereis wg | tr ' ' '\n' | grep bin").Stdout;
Configuration.Wireguard.WireguardQuickBin = _commandRunner
.Run("whereis wg-quick | tr ' ' '\n' | grep bin").Stdout;
Configuration.Wireguard.Interfaces = new();
Configuration.Wireguard.PrimaryDns = new("8.8.8.8", UriKind.RelativeOrAbsolute);
Configuration.Wireguard.SecondaryDns = new("8.8.4.4", UriKind.RelativeOrAbsolute);
var publicIp = Network.GetPublicIPAddress();
Configuration.Wireguard.Endpoint = publicIp == default
? default
: new(publicIp.ToString(), UriKind.RelativeOrAbsolute);
}

public abstract void Load();
public abstract void Save();
public abstract string Export();
}
30 changes: 30 additions & 0 deletions Linguard/Core/Managers/DefaultFileConfigurationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Linguard.Core.Configuration;
using Linguard.Core.Configuration.Serialization;
using Linguard.Core.OS;
using Linguard.Core.Utils;

namespace Linguard.Core.Managers;

public abstract class DefaultFileConfigurationManager : FileConfigurationManager {

protected DefaultFileConfigurationManager(IConfiguration configuration, IWorkingDirectory workingDirectory,
ICommandRunner commandRunner, IConfigurationSerializer serializer)
: base(configuration, workingDirectory, commandRunner, serializer) {
}

private FileInfo? _configurationFile;

protected sealed override FileInfo ConfigurationFile {
get {
if (_configurationFile != default) return _configurationFile;
var filename = Path.Combine(WorkingDirectory.BaseDirectory.FullName, AssemblyInfo.Product.ToLower());
var tries = 0;
while (tries < SupportedExtensions.Length && _configurationFile is not { Exists: true }) {
var filepath = Path.ChangeExtension(filename, SupportedExtensions[tries]);
_configurationFile = new FileInfo(filepath);
tries++;
}
return _configurationFile!;
}
}
}
19 changes: 8 additions & 11 deletions Linguard/Core/Managers/FileConfigurationManager.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
using Linguard.Core.Configuration;
using Linguard.Core.Configuration.Exceptions;
using Linguard.Core.Configuration.Serialization;
using Linguard.Core.OS;

namespace Linguard.Core.Managers;

public abstract class FileConfigurationManager : IConfigurationManager {
public abstract class FileConfigurationManager : ConfigurationManagerBase {

protected FileConfigurationManager(IConfiguration configuration, IWorkingDirectory workingDirectory,
IConfigurationSerializer serializer) {
ICommandRunner commandRunner, IConfigurationSerializer serializer) : base(configuration, workingDirectory, commandRunner) {
Configuration = configuration;
WorkingDirectory = workingDirectory;
Serializer = serializer;
}

public IConfiguration Configuration { get; set; }
public IWorkingDirectory WorkingDirectory { get; set; }
protected abstract FileInfo ConfigurationFile { get; }
private IConfigurationSerializer Serializer { get; }

public abstract void LoadDefaults();

public void Load() {
public abstract string[] SupportedExtensions { get; }
public override void Load() {
if (!ConfigurationFile.Exists) {
throw new ConfigurationNotLoadedError(
$"Configuration file '{ConfigurationFile.FullName}' does not exist."
Expand All @@ -36,8 +35,7 @@ public void Load() {
);
}
}

public void Save() {
public override void Save() {
try {
File.WriteAllText(ConfigurationFile.FullName, Export());
}
Expand All @@ -47,8 +45,7 @@ public void Save() {
);
}
}

public string Export() {
public override string Export() {
return Serializer.Serialize(Configuration);
}
}
72 changes: 7 additions & 65 deletions Linguard/Core/Managers/YamlConfigurationManager.cs
Original file line number Diff line number Diff line change
@@ -1,75 +1,17 @@
using System.Net;
using Linguard.Core.Configuration;
using Linguard.Core.Configuration;
using Linguard.Core.Configuration.Serialization;
using Linguard.Core.Drivers.TrafficStorage;
using Linguard.Core.Models;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Linguard.Core.Utils;
using Linguard.Log;

namespace Linguard.Core.Managers;

public class YamlConfigurationManager : FileConfigurationManager {
private static readonly string[] SupportedExtensions = {"yaml", "yml"};
public class YamlConfigurationManager : DefaultFileConfigurationManager {

private FileInfo? _configurationFile;
private readonly ICommandRunner _commandRunner;

protected sealed override FileInfo ConfigurationFile {
get {
if (_configurationFile != default) return _configurationFile;
var filename = Path.Combine(WorkingDirectory.BaseDirectory.FullName, AssemblyInfo.Product.ToLower());
var tries = 0;
while (tries < SupportedExtensions.Length && _configurationFile is not { Exists: true }) {
var filepath = Path.ChangeExtension(filename, SupportedExtensions[tries]);
_configurationFile = new FileInfo(filepath);
tries++;
}
return _configurationFile!;
}
}

public override void LoadDefaults() {
LoadWebDefaults();
LoadLoggingDefaults();
LoadTrafficDefaults();
LoadWireguardDefaults();
}

private void LoadWebDefaults() {
Configuration.Web.Style = Style.Default;
Configuration.Web.LoginAttempts = 10;
Configuration.Web.SecretKey = "";
}
private void LoadLoggingDefaults() {
Configuration.Logging.Level = LogLevel.Info;
Configuration.Logging.Overwrite = false;
}
private void LoadTrafficDefaults() {
Configuration.Traffic.Enabled = true;
Configuration.Traffic.StorageDriver = new JsonTrafficStorageDriver();
}
private void LoadWireguardDefaults() {
Configuration.Wireguard.Interfaces = new HashSet<Interface>();
Configuration.Wireguard.IptablesBin = _commandRunner
.Run("whereis iptables | tr ' ' '\n' | grep bin").Stdout;
Configuration.Wireguard.WireguardBin = _commandRunner
.Run("whereis wg | tr ' ' '\n' | grep bin").Stdout;
Configuration.Wireguard.WireguardQuickBin = _commandRunner
.Run("whereis wg-quick | tr ' ' '\n' | grep bin").Stdout;
Configuration.Wireguard.Interfaces = new();
Configuration.Wireguard.PrimaryDns = new("8.8.8.8", UriKind.RelativeOrAbsolute);
Configuration.Wireguard.SecondaryDns = new("8.8.4.4", UriKind.RelativeOrAbsolute);
var publicIp = Network.GetPublicIPAddress();
Configuration.Wireguard.Endpoint = publicIp == default
? default
: new(publicIp.ToString(), UriKind.RelativeOrAbsolute);
}
public override string[] SupportedExtensions => new [] {
"yaml", "yml"
};

public YamlConfigurationManager(IConfiguration configuration, IWorkingDirectory workingDirectory,
IConfigurationSerializer serializer, ICommandRunner commandRunner)
: base(configuration, workingDirectory, serializer) {
_commandRunner = commandRunner;
ICommandRunner commandRunner, IConfigurationSerializer serializer)
: base(configuration, workingDirectory, commandRunner, serializer) {
}
}

0 comments on commit 8af502d

Please sign in to comment.