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())
|
if (!_clusterConfigurationFile.DirectoryExists())
|
||||||
{
|
{
|
||||||
_logger.LogError($"Cluster not found: {clusterName}");
|
_logger.LogError($"Cluster not found: {_clusterConfigurationFile.GetDirectoryPath()}");
|
||||||
return new NotFound("Cluster not found");
|
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 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
|
AppSettings appSettings
|
||||||
) {
|
) {
|
||||||
_clusterName = clusterName;
|
_clusterName = clusterName;
|
||||||
_appSettings = appSettings;
|
|
||||||
_rootDirectory = _appSettings.ClustersRootPath;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(_clusterName))
|
if (string.IsNullOrEmpty(_clusterName))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("The provided cluster name is null or empty.");
|
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);
|
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": {
|
"AppSettings": {
|
||||||
"ApiKey": "api-key",
|
"ApiKey": "api-key",
|
||||||
"ClustersRootPath": "/tmp/projects"
|
"RootPath": "/tmp"
|
||||||
},
|
},
|
||||||
"Urls": "http://0.0.0.0:8765",
|
"Urls": "http://0.0.0.0:8765",
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user