mirror of
https://github.com/freedbygrace/PSOPNSenseAPI.git
synced 2026-07-26 20:08:30 +00:00
Fixed more threading issues in PowerShell cmdlets to ensure WriteObject and WriteError are only called from the main thread
This commit is contained in:
@@ -34,29 +34,34 @@ namespace PSOPNSenseAPI.Cmdlets
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
protected override void ProcessRecordInternal()
|
||||
{
|
||||
try
|
||||
var cronService = new CronService(ApiClient, Logger);
|
||||
|
||||
// Use our safe execution method
|
||||
var result = ExecuteAsyncTask(() => cronService.ToggleJobAsync(Uuid, true));
|
||||
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || result == null)
|
||||
{
|
||||
var cronService = new CronService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await cronService.ToggleJobAsync(Uuid, true));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron job {Uuid} enabled: {result.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await cronService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron changes applied: {applyResult.Status}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
WriteVerbose($"Cron job {Uuid} enabled: {result.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
HandleException(ex);
|
||||
// Use our safe execution method
|
||||
var applyResult = ExecuteAsyncTask(() => cronService.ApplyChangesAsync());
|
||||
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || applyResult == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteVerbose($"Cron changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,28 +33,35 @@ namespace PSOPNSenseAPI.Cmdlets
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
protected override void ProcessRecordInternal()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cronService = new CronService(ApiClient, Logger);
|
||||
var cronService = new CronService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await cronService.GetJobAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Job);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await cronService.GetJobsAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
HandleException(ex);
|
||||
// Use our safe execution method
|
||||
var result = ExecuteAsyncTask(() => cronService.GetJobAsync(Uuid));
|
||||
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteObject(result.Job);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use our safe execution method
|
||||
var result = ExecuteAsyncTask(() => cronService.GetJobsAsync());
|
||||
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,28 +33,35 @@ namespace PSOPNSenseAPI.Cmdlets
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
protected override void ProcessRecordInternal()
|
||||
{
|
||||
try
|
||||
{
|
||||
var userService = new UserService(ApiClient, Logger);
|
||||
var userService = new UserService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await userService.GetUserAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.User);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await userService.GetUsersAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
HandleException(ex);
|
||||
// Use our safe execution method
|
||||
var result = ExecuteAsyncTask(() => userService.GetUserAsync(Uuid));
|
||||
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteObject(result.User);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use our safe execution method
|
||||
var result = ExecuteAsyncTask(() => userService.GetUsersAsync());
|
||||
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,47 +103,52 @@ namespace PSOPNSenseAPI.Cmdlets
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
protected override void ProcessRecordInternal()
|
||||
{
|
||||
try
|
||||
var gatewayService = new GatewayService(ApiClient, Logger);
|
||||
|
||||
var gateway = new GatewayConfig
|
||||
{
|
||||
var gatewayService = new GatewayService(ApiClient, Logger);
|
||||
Name = Name,
|
||||
Interface = Interface,
|
||||
IpAddress = IpAddress,
|
||||
MonitorIp = MonitorIp ?? IpAddress,
|
||||
Description = Description,
|
||||
IsDefault = Default.IsPresent ? "1" : "0",
|
||||
Disabled = Disabled.IsPresent ? "1" : "0",
|
||||
Weight = Weight?.ToString() ?? "1",
|
||||
IpProtocol = IpProtocol,
|
||||
MonitorDisable = DisableMonitoring.IsPresent ? "1" : "0",
|
||||
ForceDown = ForceDown.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
var gateway = new GatewayConfig
|
||||
// Use our safe execution method
|
||||
var createResult = ExecuteAsyncTask(() => gatewayService.CreateGatewayAsync(gateway));
|
||||
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || createResult == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteVerbose($"Created gateway with UUID {createResult.Uuid}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
// Use our safe execution method
|
||||
var applyResult = ExecuteAsyncTask(() => gatewayService.ApplyGatewayChangesAsync());
|
||||
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || applyResult == null)
|
||||
{
|
||||
Name = Name,
|
||||
Interface = Interface,
|
||||
IpAddress = IpAddress,
|
||||
MonitorIp = MonitorIp ?? IpAddress,
|
||||
Description = Description,
|
||||
IsDefault = Default.IsPresent ? "1" : "0",
|
||||
Disabled = Disabled.IsPresent ? "1" : "0",
|
||||
Weight = Weight?.ToString() ?? "1",
|
||||
IpProtocol = IpProtocol,
|
||||
MonitorDisable = DisableMonitoring.IsPresent ? "1" : "0",
|
||||
ForceDown = ForceDown.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
var createTask = Task.Run(async () => await gatewayService.CreateGatewayAsync(gateway));
|
||||
var createResult = createTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created gateway with UUID {createResult.Uuid}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await gatewayService.ApplyGatewayChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Gateway changes applied: {applyResult.Status}");
|
||||
return;
|
||||
}
|
||||
|
||||
WriteObject(createResult.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
WriteVerbose($"Gateway changes applied: {applyResult.Status}");
|
||||
}
|
||||
|
||||
WriteObject(createResult.Uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,33 +66,32 @@ namespace PSOPNSenseAPI.Cmdlets
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
protected override void ProcessRecordInternal()
|
||||
{
|
||||
try
|
||||
var userService = new UserService(ApiClient, Logger);
|
||||
|
||||
var user = new UserConfig
|
||||
{
|
||||
var userService = new UserService(ApiClient, Logger);
|
||||
Username = Username,
|
||||
Password = Password,
|
||||
FullName = FullName,
|
||||
Email = Email,
|
||||
Disabled = Disabled.IsPresent ? "1" : "0",
|
||||
Groups = Groups != null ? new List<string>(Groups) : new List<string>(),
|
||||
Authorizations = Authorizations != null ? new List<string>(Authorizations) : new List<string>()
|
||||
};
|
||||
|
||||
var user = new UserConfig
|
||||
{
|
||||
Username = Username,
|
||||
Password = Password,
|
||||
FullName = FullName,
|
||||
Email = Email,
|
||||
Disabled = Disabled.IsPresent ? "1" : "0",
|
||||
Groups = Groups != null ? new List<string>(Groups) : new List<string>(),
|
||||
Authorizations = Authorizations != null ? new List<string>(Authorizations) : new List<string>()
|
||||
};
|
||||
// Use our safe execution method
|
||||
var result = ExecuteAsyncTask(() => userService.CreateUserAsync(user));
|
||||
|
||||
var task = Task.Run(async () => await userService.CreateUserAsync(user));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created user with UUID {result.Uuid}");
|
||||
WriteObject(result.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || result == null)
|
||||
{
|
||||
HandleException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
WriteVerbose($"Created user with UUID {result.Uuid}");
|
||||
WriteObject(result.Uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,67 +47,69 @@ namespace PSOPNSenseAPI.Cmdlets
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
protected override void ProcessRecordInternal()
|
||||
{
|
||||
try
|
||||
if (!ShouldProcess("OPNSense firewall", "Update firmware"))
|
||||
{
|
||||
if (!ShouldProcess("OPNSense firewall", "Update firmware"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var firmwareService = new FirmwareService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await firmwareService.UpdateAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Firmware update initiated: {result.Status}");
|
||||
WriteObject($"Firmware update initiated: {result.Status}");
|
||||
|
||||
if (Wait.IsPresent)
|
||||
{
|
||||
WriteVerbose($"Waiting for firmware update to complete (timeout: {Timeout} seconds, interval: {Interval} seconds)");
|
||||
WriteObject("Waiting for firmware update to complete...");
|
||||
|
||||
DateTime startTime = DateTime.Now;
|
||||
bool completed = false;
|
||||
|
||||
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
||||
{
|
||||
var statusTask = Task.Run(async () => await firmwareService.GetStatusAsync());
|
||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
if (statusResult.Status == "done")
|
||||
{
|
||||
WriteVerbose("Firmware update completed successfully");
|
||||
WriteObject("Firmware update completed successfully");
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
else if (statusResult.Status == "error")
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception($"Firmware update failed: {statusResult.Log}"),
|
||||
"FirmwareUpdateFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
WriteVerbose($"Firmware update status: {statusResult.Status}");
|
||||
Thread.Sleep(Interval * 1000);
|
||||
}
|
||||
|
||||
if (!completed)
|
||||
{
|
||||
WriteWarning($"Timed out waiting for firmware update to complete after {Timeout} seconds");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
var firmwareService = new FirmwareService(ApiClient, Logger);
|
||||
|
||||
// Use our safe execution method
|
||||
var result = ExecuteAsyncTask(() => firmwareService.UpdateAsync());
|
||||
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || result == null)
|
||||
{
|
||||
HandleException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
WriteVerbose($"Firmware update initiated: {result.Status}");
|
||||
WriteObject($"Firmware update initiated: {result.Status}");
|
||||
|
||||
if (Wait.IsPresent)
|
||||
{
|
||||
WriteVerbose($"Waiting for firmware update to complete (timeout: {Timeout} seconds, interval: {Interval} seconds)");
|
||||
WriteObject("Waiting for firmware update to complete...");
|
||||
|
||||
DateTime startTime = DateTime.Now;
|
||||
bool completed = false;
|
||||
|
||||
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
||||
{
|
||||
// Use our safe execution method
|
||||
var statusResult = ExecuteAsyncTask(() => firmwareService.GetStatusAsync());
|
||||
|
||||
// Break if an exception occurred
|
||||
if (ProcessingException != null || statusResult == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (statusResult.Status == "done")
|
||||
{
|
||||
WriteVerbose("Firmware update completed successfully");
|
||||
WriteObject("Firmware update completed successfully");
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
else if (statusResult.Status == "error")
|
||||
{
|
||||
// Store the exception to be processed in ProcessRecord
|
||||
ProcessingException = new Exception($"Firmware update failed: {statusResult.Log}");
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
WriteVerbose($"Firmware update status: {statusResult.Status}");
|
||||
Thread.Sleep(Interval * 1000);
|
||||
}
|
||||
|
||||
if (!completed && ProcessingException == null)
|
||||
{
|
||||
WriteWarning($"Timed out waiting for firmware update to complete after {Timeout} seconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,76 +54,82 @@ namespace PSOPNSenseAPI.Cmdlets
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
protected override void ProcessRecordInternal()
|
||||
{
|
||||
try
|
||||
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Upgrade firmware"))
|
||||
{
|
||||
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Upgrade firmware"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var firmwareService = new FirmwareService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await firmwareService.UpgradeAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Firmware upgrade initiated: {result.Status}");
|
||||
WriteObject($"Firmware upgrade initiated: {result.Status}");
|
||||
|
||||
if (Wait.IsPresent)
|
||||
{
|
||||
WriteVerbose($"Waiting for firmware upgrade to complete (timeout: {Timeout} seconds, interval: {Interval} seconds)");
|
||||
WriteObject("Waiting for firmware upgrade to complete...");
|
||||
|
||||
DateTime startTime = DateTime.Now;
|
||||
bool completed = false;
|
||||
|
||||
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
var statusTask = Task.Run(async () => await firmwareService.GetStatusAsync());
|
||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
if (statusResult.Status == "done")
|
||||
{
|
||||
WriteVerbose("Firmware upgrade completed successfully");
|
||||
WriteObject("Firmware upgrade completed successfully");
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
else if (statusResult.Status == "error")
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception($"Firmware upgrade failed: {statusResult.Log}"),
|
||||
"FirmwareUpgradeFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
WriteVerbose($"Firmware upgrade status: {statusResult.Status}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// The firewall might be rebooting, so we'll ignore errors during the wait
|
||||
WriteVerbose($"Error checking status (firewall might be rebooting): {ex.Message}");
|
||||
}
|
||||
|
||||
Thread.Sleep(Interval * 1000);
|
||||
}
|
||||
|
||||
if (!completed)
|
||||
{
|
||||
WriteWarning($"Timed out waiting for firmware upgrade to complete after {Timeout} seconds");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
var firmwareService = new FirmwareService(ApiClient, Logger);
|
||||
|
||||
// Use our safe execution method
|
||||
var result = ExecuteAsyncTask(() => firmwareService.UpgradeAsync());
|
||||
|
||||
// Only continue if no exception occurred
|
||||
if (ProcessingException != null || result == null)
|
||||
{
|
||||
HandleException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
WriteVerbose($"Firmware upgrade initiated: {result.Status}");
|
||||
WriteObject($"Firmware upgrade initiated: {result.Status}");
|
||||
|
||||
if (Wait.IsPresent)
|
||||
{
|
||||
WriteVerbose($"Waiting for firmware upgrade to complete (timeout: {Timeout} seconds, interval: {Interval} seconds)");
|
||||
WriteObject("Waiting for firmware upgrade to complete...");
|
||||
|
||||
DateTime startTime = DateTime.Now;
|
||||
bool completed = false;
|
||||
|
||||
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Use our safe execution method
|
||||
var statusResult = ExecuteAsyncTask(() => firmwareService.GetStatusAsync());
|
||||
|
||||
// Skip this iteration if an exception occurred
|
||||
if (ProcessingException != null || statusResult == null)
|
||||
{
|
||||
// Clear the exception since we're ignoring it during the wait
|
||||
ProcessingException = null;
|
||||
WriteVerbose("Error checking status (firewall might be rebooting)");
|
||||
Thread.Sleep(Interval * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (statusResult.Status == "done")
|
||||
{
|
||||
WriteVerbose("Firmware upgrade completed successfully");
|
||||
WriteObject("Firmware upgrade completed successfully");
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
else if (statusResult.Status == "error")
|
||||
{
|
||||
// Store the exception to be processed in ProcessRecord
|
||||
ProcessingException = new Exception($"Firmware upgrade failed: {statusResult.Log}");
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
WriteVerbose($"Firmware upgrade status: {statusResult.Status}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// The firewall might be rebooting, so we'll ignore errors during the wait
|
||||
WriteVerbose($"Error checking status (firewall might be rebooting): {ex.Message}");
|
||||
}
|
||||
|
||||
Thread.Sleep(Interval * 1000);
|
||||
}
|
||||
|
||||
if (!completed && ProcessingException == null)
|
||||
{
|
||||
WriteWarning($"Timed out waiting for firmware upgrade to complete after {Timeout} seconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
RootModule = 'lib\PSOPNSenseAPI.dll'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '2025.04.15.1228'
|
||||
ModuleVersion = '2025.04.15.1234'
|
||||
|
||||
# Supported PSEditions
|
||||
CompatiblePSEditions = @('Desktop', 'Core')
|
||||
|
||||
Reference in New Issue
Block a user