mirror of
https://github.com/freedbygrace/PSOPNSenseAPI.git
synced 2026-08-29 03:47:13 +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,30 +34,35 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes the cmdlet
|
/// Processes the cmdlet
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecordInternal()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var cronService = new CronService(ApiClient, Logger);
|
var cronService = new CronService(ApiClient, Logger);
|
||||||
|
|
||||||
var task = Task.Run(async () => await cronService.ToggleJobAsync(Uuid, true));
|
// Use our safe execution method
|
||||||
var result = task.GetAwaiter().GetResult();
|
var result = ExecuteAsyncTask(() => cronService.ToggleJobAsync(Uuid, true));
|
||||||
|
|
||||||
|
// Only continue if no exception occurred
|
||||||
|
if (ProcessingException != null || result == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteVerbose($"Cron job {Uuid} enabled: {result.Result}");
|
WriteVerbose($"Cron job {Uuid} enabled: {result.Result}");
|
||||||
|
|
||||||
// Apply the changes if requested
|
// Apply the changes if requested
|
||||||
if (Apply.IsPresent)
|
if (Apply.IsPresent)
|
||||||
{
|
{
|
||||||
var applyTask = Task.Run(async () => await cronService.ApplyChangesAsync());
|
// Use our safe execution method
|
||||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
var applyResult = ExecuteAsyncTask(() => cronService.ApplyChangesAsync());
|
||||||
|
|
||||||
|
// Only continue if no exception occurred
|
||||||
|
if (ProcessingException != null || applyResult == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteVerbose($"Cron changes applied: {applyResult.Status}");
|
WriteVerbose($"Cron changes applied: {applyResult.Status}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
HandleException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,29 +33,36 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes the cmdlet
|
/// Processes the cmdlet
|
||||||
/// </summary>
|
/// </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")
|
if (ParameterSetName == "ByUuid")
|
||||||
{
|
{
|
||||||
var task = Task.Run(async () => await cronService.GetJobAsync(Uuid));
|
// Use our safe execution method
|
||||||
var result = task.GetAwaiter().GetResult();
|
var result = ExecuteAsyncTask(() => cronService.GetJobAsync(Uuid));
|
||||||
|
|
||||||
|
// Only continue if no exception occurred
|
||||||
|
if (ProcessingException != null || result == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteObject(result.Job);
|
WriteObject(result.Job);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var task = Task.Run(async () => await cronService.GetJobsAsync());
|
// Use our safe execution method
|
||||||
var result = task.GetAwaiter().GetResult();
|
var result = ExecuteAsyncTask(() => cronService.GetJobsAsync());
|
||||||
|
|
||||||
|
// Only continue if no exception occurred
|
||||||
|
if (ProcessingException != null || result == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteObject(result.Rows, true);
|
WriteObject(result.Rows, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
HandleException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,29 +33,36 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes the cmdlet
|
/// Processes the cmdlet
|
||||||
/// </summary>
|
/// </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")
|
if (ParameterSetName == "ByUuid")
|
||||||
{
|
{
|
||||||
var task = Task.Run(async () => await userService.GetUserAsync(Uuid));
|
// Use our safe execution method
|
||||||
var result = task.GetAwaiter().GetResult();
|
var result = ExecuteAsyncTask(() => userService.GetUserAsync(Uuid));
|
||||||
|
|
||||||
|
// Only continue if no exception occurred
|
||||||
|
if (ProcessingException != null || result == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteObject(result.User);
|
WriteObject(result.User);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var task = Task.Run(async () => await userService.GetUsersAsync());
|
// Use our safe execution method
|
||||||
var result = task.GetAwaiter().GetResult();
|
var result = ExecuteAsyncTask(() => userService.GetUsersAsync());
|
||||||
|
|
||||||
|
// Only continue if no exception occurred
|
||||||
|
if (ProcessingException != null || result == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteObject(result.Rows, true);
|
WriteObject(result.Rows, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
HandleException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,9 +103,7 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes the cmdlet
|
/// Processes the cmdlet
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecordInternal()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var gatewayService = new GatewayService(ApiClient, Logger);
|
var gatewayService = new GatewayService(ApiClient, Logger);
|
||||||
|
|
||||||
@@ -124,26 +122,33 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
ForceDown = ForceDown.IsPresent ? "1" : "0"
|
ForceDown = ForceDown.IsPresent ? "1" : "0"
|
||||||
};
|
};
|
||||||
|
|
||||||
var createTask = Task.Run(async () => await gatewayService.CreateGatewayAsync(gateway));
|
// Use our safe execution method
|
||||||
var createResult = createTask.GetAwaiter().GetResult();
|
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}");
|
WriteVerbose($"Created gateway with UUID {createResult.Uuid}");
|
||||||
|
|
||||||
// Apply changes if requested
|
// Apply changes if requested
|
||||||
if (Apply.IsPresent)
|
if (Apply.IsPresent)
|
||||||
{
|
{
|
||||||
var applyTask = Task.Run(async () => await gatewayService.ApplyGatewayChangesAsync());
|
// Use our safe execution method
|
||||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
var applyResult = ExecuteAsyncTask(() => gatewayService.ApplyGatewayChangesAsync());
|
||||||
|
|
||||||
|
// Only continue if no exception occurred
|
||||||
|
if (ProcessingException != null || applyResult == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteVerbose($"Gateway changes applied: {applyResult.Status}");
|
WriteVerbose($"Gateway changes applied: {applyResult.Status}");
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteObject(createResult.Uuid);
|
WriteObject(createResult.Uuid);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
HandleException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes the cmdlet
|
/// Processes the cmdlet
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecordInternal()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var userService = new UserService(ApiClient, Logger);
|
var userService = new UserService(ApiClient, Logger);
|
||||||
|
|
||||||
@@ -83,16 +81,17 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
Authorizations = Authorizations != null ? new List<string>(Authorizations) : new List<string>()
|
Authorizations = Authorizations != null ? new List<string>(Authorizations) : new List<string>()
|
||||||
};
|
};
|
||||||
|
|
||||||
var task = Task.Run(async () => await userService.CreateUserAsync(user));
|
// Use our safe execution method
|
||||||
var result = task.GetAwaiter().GetResult();
|
var result = ExecuteAsyncTask(() => userService.CreateUserAsync(user));
|
||||||
|
|
||||||
|
// Only continue if no exception occurred
|
||||||
|
if (ProcessingException != null || result == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteVerbose($"Created user with UUID {result.Uuid}");
|
WriteVerbose($"Created user with UUID {result.Uuid}");
|
||||||
WriteObject(result.Uuid);
|
WriteObject(result.Uuid);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
HandleException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,9 +47,7 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes the cmdlet
|
/// Processes the cmdlet
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecordInternal()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
if (!ShouldProcess("OPNSense firewall", "Update firmware"))
|
if (!ShouldProcess("OPNSense firewall", "Update firmware"))
|
||||||
{
|
{
|
||||||
@@ -58,8 +56,14 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
|
|
||||||
var firmwareService = new FirmwareService(ApiClient, Logger);
|
var firmwareService = new FirmwareService(ApiClient, Logger);
|
||||||
|
|
||||||
var task = Task.Run(async () => await firmwareService.UpdateAsync());
|
// Use our safe execution method
|
||||||
var result = task.GetAwaiter().GetResult();
|
var result = ExecuteAsyncTask(() => firmwareService.UpdateAsync());
|
||||||
|
|
||||||
|
// Only continue if no exception occurred
|
||||||
|
if (ProcessingException != null || result == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteVerbose($"Firmware update initiated: {result.Status}");
|
WriteVerbose($"Firmware update initiated: {result.Status}");
|
||||||
WriteObject($"Firmware update initiated: {result.Status}");
|
WriteObject($"Firmware update initiated: {result.Status}");
|
||||||
@@ -74,8 +78,14 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
|
|
||||||
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
||||||
{
|
{
|
||||||
var statusTask = Task.Run(async () => await firmwareService.GetStatusAsync());
|
// Use our safe execution method
|
||||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
var statusResult = ExecuteAsyncTask(() => firmwareService.GetStatusAsync());
|
||||||
|
|
||||||
|
// Break if an exception occurred
|
||||||
|
if (ProcessingException != null || statusResult == null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (statusResult.Status == "done")
|
if (statusResult.Status == "done")
|
||||||
{
|
{
|
||||||
@@ -86,11 +96,8 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
}
|
}
|
||||||
else if (statusResult.Status == "error")
|
else if (statusResult.Status == "error")
|
||||||
{
|
{
|
||||||
WriteError(new ErrorRecord(
|
// Store the exception to be processed in ProcessRecord
|
||||||
new Exception($"Firmware update failed: {statusResult.Log}"),
|
ProcessingException = new Exception($"Firmware update failed: {statusResult.Log}");
|
||||||
"FirmwareUpdateFailed",
|
|
||||||
ErrorCategory.InvalidOperation,
|
|
||||||
null));
|
|
||||||
completed = true;
|
completed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -99,16 +106,11 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
Thread.Sleep(Interval * 1000);
|
Thread.Sleep(Interval * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!completed)
|
if (!completed && ProcessingException == null)
|
||||||
{
|
{
|
||||||
WriteWarning($"Timed out waiting for firmware update to complete after {Timeout} seconds");
|
WriteWarning($"Timed out waiting for firmware update to complete after {Timeout} seconds");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
HandleException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,9 +54,7 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes the cmdlet
|
/// Processes the cmdlet
|
||||||
/// </summary>
|
/// </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"))
|
||||||
{
|
{
|
||||||
@@ -65,8 +63,14 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
|
|
||||||
var firmwareService = new FirmwareService(ApiClient, Logger);
|
var firmwareService = new FirmwareService(ApiClient, Logger);
|
||||||
|
|
||||||
var task = Task.Run(async () => await firmwareService.UpgradeAsync());
|
// Use our safe execution method
|
||||||
var result = task.GetAwaiter().GetResult();
|
var result = ExecuteAsyncTask(() => firmwareService.UpgradeAsync());
|
||||||
|
|
||||||
|
// Only continue if no exception occurred
|
||||||
|
if (ProcessingException != null || result == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
WriteVerbose($"Firmware upgrade initiated: {result.Status}");
|
WriteVerbose($"Firmware upgrade initiated: {result.Status}");
|
||||||
WriteObject($"Firmware upgrade initiated: {result.Status}");
|
WriteObject($"Firmware upgrade initiated: {result.Status}");
|
||||||
@@ -83,8 +87,18 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var statusTask = Task.Run(async () => await firmwareService.GetStatusAsync());
|
// Use our safe execution method
|
||||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
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")
|
if (statusResult.Status == "done")
|
||||||
{
|
{
|
||||||
@@ -95,11 +109,8 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
}
|
}
|
||||||
else if (statusResult.Status == "error")
|
else if (statusResult.Status == "error")
|
||||||
{
|
{
|
||||||
WriteError(new ErrorRecord(
|
// Store the exception to be processed in ProcessRecord
|
||||||
new Exception($"Firmware upgrade failed: {statusResult.Log}"),
|
ProcessingException = new Exception($"Firmware upgrade failed: {statusResult.Log}");
|
||||||
"FirmwareUpgradeFailed",
|
|
||||||
ErrorCategory.InvalidOperation,
|
|
||||||
null));
|
|
||||||
completed = true;
|
completed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -115,16 +126,11 @@ namespace PSOPNSenseAPI.Cmdlets
|
|||||||
Thread.Sleep(Interval * 1000);
|
Thread.Sleep(Interval * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!completed)
|
if (!completed && ProcessingException == null)
|
||||||
{
|
{
|
||||||
WriteWarning($"Timed out waiting for firmware upgrade to complete after {Timeout} seconds");
|
WriteWarning($"Timed out waiting for firmware upgrade to complete after {Timeout} seconds");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
HandleException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
RootModule = 'lib\PSOPNSenseAPI.dll'
|
RootModule = 'lib\PSOPNSenseAPI.dll'
|
||||||
|
|
||||||
# Version number of this module.
|
# Version number of this module.
|
||||||
ModuleVersion = '2025.04.15.1228'
|
ModuleVersion = '2025.04.15.1234'
|
||||||
|
|
||||||
# Supported PSEditions
|
# Supported PSEditions
|
||||||
CompatiblePSEditions = @('Desktop', 'Core')
|
CompatiblePSEditions = @('Desktop', 'Core')
|
||||||
|
|||||||
Reference in New Issue
Block a user