Implement Devices controller and service
This commit is contained in:
parent
41ec149b79
commit
b69d6d50c7
@ -37,7 +37,7 @@ public class ClustersController : ControllerBase
|
||||
}
|
||||
if (!_clusterConfigurationFile.DirectoryExists())
|
||||
{
|
||||
_logger.LogError($"Cluster not found: {clusterName}");
|
||||
_logger.LogError($"Cluster not found: {_clusterConfigurationFile.GetDirectoryPath()}");
|
||||
return new NotFound("Cluster not found");
|
||||
}
|
||||
|
||||
|
||||
147
src/DevicesRestApi/Controllers/DevicesController.cs
Normal file
147
src/DevicesRestApi/Controllers/DevicesController.cs
Normal file
@ -0,0 +1,147 @@
|
||||
namespace DevicesRestApi.Controllers;
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Diagnostics;
|
||||
|
||||
using DevicesRestApi.Helpers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class DevicesController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<ClustersController> _logger;
|
||||
|
||||
private readonly AppSettings _appSettings;
|
||||
|
||||
public DevicesController(
|
||||
ILogger<ClustersController> logger,
|
||||
IOptions<AppSettings> appSettings
|
||||
) {
|
||||
_logger = logger;
|
||||
_appSettings = appSettings.Value;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("~/devices/{deviceName}")]
|
||||
public IActionResult UpdateDeviceConfiguration(string deviceName, UpdateDeviceRequest request)
|
||||
{
|
||||
DeviceConfigurationFile configurationFile = null;
|
||||
try {
|
||||
configurationFile = GetConfigurationFile(deviceName);
|
||||
}
|
||||
catch (ConfigurationException e)
|
||||
{
|
||||
_logger.LogWarning(e.Message);
|
||||
return BadRequest(new{
|
||||
message = e.Message,
|
||||
});
|
||||
}
|
||||
var command = createCommand(
|
||||
configurationFile.GetFilePath(),
|
||||
request.clusterName
|
||||
);
|
||||
|
||||
executeCommand(command);
|
||||
|
||||
return new Ok("Device configuration updated");
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("~/devices/{deviceName}")]
|
||||
public IActionResult DeleteDeviceConfiguration(string deviceName)
|
||||
{
|
||||
DeviceConfigurationFile configurationFile = null;
|
||||
try {
|
||||
configurationFile = GetConfigurationFile(deviceName);
|
||||
}
|
||||
catch (ConfigurationException e)
|
||||
{
|
||||
_logger.LogWarning(e.Message);
|
||||
return BadRequest(new{
|
||||
message = e.Message,
|
||||
});
|
||||
}
|
||||
|
||||
var command = createCommand(
|
||||
configurationFile.GetFilePath(),
|
||||
"no-cluster"
|
||||
);
|
||||
|
||||
executeCommand(command);
|
||||
|
||||
return new Ok("Device configuration updated");
|
||||
}
|
||||
|
||||
private DeviceConfigurationFile GetConfigurationFile(string deviceName)
|
||||
{
|
||||
DeviceConfigurationFile configurationFile = null;
|
||||
try {
|
||||
configurationFile = new DeviceConfigurationFile(deviceName, _appSettings);
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
_logger.LogError($"Something went wrong: {e}");
|
||||
throw new ConfigurationException($"Something went wrong: {e}");
|
||||
}
|
||||
if (!configurationFile.FileExists())
|
||||
{
|
||||
var message = "Configuration file doesn't exist";
|
||||
_logger.LogError(message);
|
||||
throw new ConfigurationException(message);
|
||||
}
|
||||
return configurationFile;
|
||||
}
|
||||
|
||||
private string createCommand(string filePath, string clusterName)
|
||||
{
|
||||
return $"sed -i -E 's/^project\\s?=.*/project = {clusterName}/' {filePath}";
|
||||
}
|
||||
|
||||
private void executeCommand(string command)
|
||||
{
|
||||
_logger.LogDebug($"Executing the command: {command}");
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "/bin/bash",
|
||||
Arguments = $"-c \"{command}\"",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
|
||||
process.Start();
|
||||
|
||||
string error = process.StandardError.ReadToEnd();
|
||||
|
||||
process.WaitForExit();
|
||||
|
||||
if (process.ExitCode > 0)
|
||||
{
|
||||
var message = error ?? "Unknown error";
|
||||
message = $"An error occurred during the execution of the command: {message}";
|
||||
_logger.LogError(message);
|
||||
throw new Exception(message);
|
||||
}
|
||||
}
|
||||
|
||||
public class CommandRequest
|
||||
{
|
||||
public string ClusterName { get; set; }
|
||||
public string DeviceName { get; set; }
|
||||
}
|
||||
|
||||
public class ConfigurationException : Exception
|
||||
{
|
||||
public ConfigurationException() : base() { }
|
||||
|
||||
public ConfigurationException(string message) : base(message) { }
|
||||
|
||||
public ConfigurationException(string message, Exception inner) : base(message, inner) { }
|
||||
}
|
||||
}
|
||||
@ -4,5 +4,5 @@ public class AppSettings
|
||||
{
|
||||
public string ApiKey { get; set; } = string.Empty;
|
||||
|
||||
public string ClustersRootPath { get; set; } = string.Empty;
|
||||
public string RootPath { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
@ -15,20 +15,26 @@ public class ClusterConfigurationFile
|
||||
AppSettings appSettings
|
||||
) {
|
||||
_clusterName = clusterName;
|
||||
_appSettings = appSettings;
|
||||
_rootDirectory = _appSettings.ClustersRootPath;
|
||||
|
||||
if (string.IsNullOrEmpty(_clusterName))
|
||||
{
|
||||
throw new ArgumentException("The provided cluster name is null or empty.");
|
||||
}
|
||||
if (string.IsNullOrEmpty(_rootDirectory))
|
||||
|
||||
_appSettings = appSettings;
|
||||
var rootPath = _appSettings.RootPath;
|
||||
if (string.IsNullOrEmpty(rootPath))
|
||||
{
|
||||
throw new ArgumentException("Clusters root directory is not configured.");
|
||||
throw new ArgumentException("Root path is not configured.");
|
||||
}
|
||||
|
||||
_rootDirectory = Path.Combine(rootPath, "projects");
|
||||
if (!Directory.Exists(_rootDirectory))
|
||||
{
|
||||
throw new ArgumentException($"Clusters directory doesn't exist: {_rootDirectory}.");
|
||||
}
|
||||
}
|
||||
|
||||
private string GetDirectoryPath()
|
||||
public string GetDirectoryPath()
|
||||
{
|
||||
return Path.Combine(_rootDirectory, _clusterName);
|
||||
}
|
||||
|
||||
81
src/DevicesRestApi/Helpers/DeviceConfigurationFile.cs
Normal file
81
src/DevicesRestApi/Helpers/DeviceConfigurationFile.cs
Normal file
@ -0,0 +1,81 @@
|
||||
namespace DevicesRestApi.Helpers;
|
||||
|
||||
public class DeviceConfigurationFile
|
||||
{
|
||||
private readonly string _rootDirectory;
|
||||
|
||||
private readonly string _deviceName;
|
||||
|
||||
private const string SettingsFilename = "settings.conf";
|
||||
|
||||
private readonly AppSettings _appSettings;
|
||||
|
||||
public DeviceConfigurationFile(
|
||||
string deviceName,
|
||||
AppSettings appSettings
|
||||
) {
|
||||
_deviceName = deviceName;
|
||||
if (string.IsNullOrEmpty(_deviceName))
|
||||
{
|
||||
throw new ArgumentException("The provided device name is null or empty.");
|
||||
}
|
||||
|
||||
_appSettings = appSettings;
|
||||
var rootPath = _appSettings.RootPath;
|
||||
if (string.IsNullOrEmpty(rootPath))
|
||||
{
|
||||
throw new ArgumentException("Root path is not configured.");
|
||||
}
|
||||
|
||||
_rootDirectory = Path.Combine(rootPath, "devices");
|
||||
if (!Directory.Exists(_rootDirectory))
|
||||
{
|
||||
throw new ArgumentException($"Devices directory doesn't exist: {_rootDirectory}.");
|
||||
}
|
||||
}
|
||||
|
||||
public string GetDirectoryPath()
|
||||
{
|
||||
return Path.Combine(_rootDirectory, _deviceName);
|
||||
}
|
||||
|
||||
public string GetFilePath()
|
||||
{
|
||||
return Path.Combine(GetDirectoryPath(), SettingsFilename);
|
||||
}
|
||||
|
||||
public bool FileExists()
|
||||
{
|
||||
return File.Exists(GetFilePath());
|
||||
}
|
||||
|
||||
public bool DirectoryExists()
|
||||
{
|
||||
return Directory.Exists(GetDirectoryPath());
|
||||
}
|
||||
|
||||
private void CreateDirectory()
|
||||
{
|
||||
Directory.CreateDirectory(GetDirectoryPath());
|
||||
}
|
||||
|
||||
private void CreateFile()
|
||||
{
|
||||
using (FileStream fs = File.Create(GetFilePath()))
|
||||
{
|
||||
// The file is created and opened, we don't need to write anything to it
|
||||
}
|
||||
}
|
||||
|
||||
public void Create()
|
||||
{
|
||||
if (!DirectoryExists())
|
||||
{
|
||||
CreateDirectory();
|
||||
}
|
||||
if (!FileExists())
|
||||
{
|
||||
CreateFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
6
src/DevicesRestApi/Helpers/UpdateDeviceRequest.cs
Normal file
6
src/DevicesRestApi/Helpers/UpdateDeviceRequest.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace DevicesRestApi.Helpers;
|
||||
|
||||
public class UpdateDeviceRequest
|
||||
{
|
||||
public string clusterName { get; set; }
|
||||
}
|
||||
@ -8,7 +8,7 @@
|
||||
},
|
||||
"AppSettings": {
|
||||
"ApiKey": "api-key",
|
||||
"ClustersRootPath": "/tmp/projects"
|
||||
"RootPath": "/tmp"
|
||||
},
|
||||
"Urls": "http://0.0.0.0:8765",
|
||||
"AllowedHosts": "*",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user