RustImplementation #49

Merged
mysticmomba merged 33 commits from RustImplementation into master 2025-12-17 14:19:20 -05:00
Showing only changes of commit 66eb101c5d - Show all commits
+24 -24
View File
@@ -206,21 +206,21 @@ class AgentMoveOperations(Widget):
f"Operation: {operation_name}", f"Operation: {operation_name}",
f"{'=' * 50}", f"{'=' * 50}",
"", "",
f"✅ Successful ({len(successful)}):", f" Successful ({len(successful)}):",
] ]
if successful: if successful:
for agent, result in successful: for agent, result in successful:
results_lines.append(f" ✅ {agent.hostname}") results_lines.append(f" {agent.hostname}")
else: else:
results_lines.append(" (none)") results_lines.append(" (none)")
results_lines.append("") results_lines.append("")
results_lines.append(f"❌ Failed ({len(unsuccessful)}):") results_lines.append(f" Failed ({len(unsuccessful)}):")
if unsuccessful: if unsuccessful:
for agent, error in unsuccessful: for agent, error in unsuccessful:
results_lines.append(f" ❌ {agent.hostname}: {error}") results_lines.append(f" {agent.hostname}: {error}")
else: else:
results_lines.append(" (none)") results_lines.append(" (none)")
@@ -255,9 +255,9 @@ class AgentMoveOperations(Widget):
- Operations panel: 1/3 width - Operations panel: 1/3 width
- Results area: Initially hidden, shown after operation completion - Results area: Initially hidden, shown after operation completion
""" """
yield Header(show_clock=True, icon="⚙️") yield Header(show_clock=True, icon="⚙️")
title_text = Static( title_text = Static(
f"🖥️ Agent Operations - {len(self.agents)} device(s) selected", f"🖥️ Agent Operations - {len(self.agents)} device(s) selected",
id="move_ops_title", id="move_ops_title",
) )
title_text.styles.margin = (0, 0, 1, 0) title_text.styles.margin = (0, 0, 1, 0)
@@ -292,32 +292,32 @@ class AgentMoveOperations(Widget):
yield operations_label yield operations_label
# Operation buttons # Operation buttons
export_csv_btn = Button("📄 Export CSV", id="export_csv_btn") export_csv_btn = Button("📄 Export CSV", id="export_csv_btn")
export_csv_btn.styles.width = "100%" export_csv_btn.styles.width = "100%"
export_csv_btn.styles.margin = (0, 0, 1, 0) export_csv_btn.styles.margin = (0, 0, 1, 0)
yield export_csv_btn yield export_csv_btn
local_approval_btn = Button( local_approval_btn = Button(
"✔️ Local Approval Mode", id="local_approval_btn" "✔️ Local Approval Mode", id="local_approval_btn"
) )
local_approval_btn.styles.width = "100%" local_approval_btn.styles.width = "100%"
local_approval_btn.styles.margin = (0, 0, 1, 0) local_approval_btn.styles.margin = (0, 0, 1, 0)
yield local_approval_btn yield local_approval_btn
otp_gen_btn = Button("🎫 Generate One Time Passes", id="otp_gen_btn") otp_gen_btn = Button("🎫 Generate One Time Passes", id="otp_gen_btn")
otp_gen_btn.styles.width = "100%" otp_gen_btn.styles.width = "100%"
otp_gen_btn.styles.margin = (0, 0, 1, 0) otp_gen_btn.styles.margin = (0, 0, 1, 0)
yield otp_gen_btn yield otp_gen_btn
toggle_enforcement_btn = Button( toggle_enforcement_btn = Button(
"🔄 Toggle Audit/Enforcement", id="toggle_enforcement_btn" "🔄 Toggle Audit/Enforcement", id="toggle_enforcement_btn"
) )
toggle_enforcement_btn.styles.width = "100%" toggle_enforcement_btn.styles.width = "100%"
toggle_enforcement_btn.styles.margin = (0, 0, 1, 0) toggle_enforcement_btn.styles.margin = (0, 0, 1, 0)
yield toggle_enforcement_btn yield toggle_enforcement_btn
other_policy_btn = Button( other_policy_btn = Button(
"🔀 Move to Other Policy", id="other_policy_btn" "🔀 Move to Other Policy", id="other_policy_btn"
) )
other_policy_btn.styles.width = "100%" other_policy_btn.styles.width = "100%"
other_policy_btn.styles.margin = (0, 0, 1, 0) other_policy_btn.styles.margin = (0, 0, 1, 0)
@@ -391,17 +391,17 @@ class AgentMoveOperations(Widget):
pyperclip.copy(results_text.text) pyperclip.copy(results_text.text)
self.app.notify( self.app.notify(
"📋✅ Results copied to clipboard!", "📋✅ Results copied to clipboard!",
severity="information", severity="information",
timeout=2, timeout=2,
) )
except ImportError: except ImportError:
self.app.notify( self.app.notify(
"❌ pyperclip not installed. Run: pip install pyperclip", " pyperclip not installed. Run: pip install pyperclip",
severity="warning", severity="warning",
) )
except Exception as e: except Exception as e:
self.app.notify(f"❌ Failed to copy: {str(e)}", severity="error") self.app.notify(f" Failed to copy: {str(e)}", severity="error")
event.stop() event.stop()
elif btn_id == "export_csv_btn": elif btn_id == "export_csv_btn":
self._start_export_csv_operation() self._start_export_csv_operation()
@@ -452,7 +452,7 @@ class AgentMoveOperations(Widget):
self.operation_in_progress = True self.operation_in_progress = True
status_label = self.query_one("#status_label", Static) status_label = self.query_one("#status_label", Static)
status_label.update("✔️ Moving agents to local approval...") status_label.update("✔️ Moving agents to local approval...")
# Get API from app # Get API from app
api = self.app.api api = self.app.api
@@ -487,12 +487,12 @@ class AgentMoveOperations(Widget):
except Exception as e: except Exception as e:
logger.error(f"Error during local approval operation: {e}") logger.error(f"Error during local approval operation: {e}")
status_label.update(f"❌ Error: {str(e)}") status_label.update(f" Error: {str(e)}")
self.operation_in_progress = False self.operation_in_progress = False
return return
self.operation_in_progress = False self.operation_in_progress = False
status_label.update("✅ Operation complete!") status_label.update(" Operation complete!")
# Display results in the widget # Display results in the widget
self._display_results("Local Approval Mode", successful, unsuccessful) self._display_results("Local Approval Mode", successful, unsuccessful)
@@ -535,9 +535,9 @@ class AgentMoveOperations(Widget):
file_path = os.path.join(str(path), filename) file_path = os.path.join(str(path), filename)
df.to_csv(file_path, index=False) df.to_csv(file_path, index=False)
successful.append(file_path) successful.append(file_path)
status_label.update(f"✅ Exported to {file_path}") status_label.update(f" Exported to {file_path}")
except Exception: except Exception:
status_label.update("❌ Failed") status_label.update(" Failed")
self.operation_in_progress = False self.operation_in_progress = False
@@ -581,7 +581,7 @@ class AgentMoveOperations(Widget):
self.operation_in_progress = True self.operation_in_progress = True
status_label = self.query_one("#status_label", Static) status_label = self.query_one("#status_label", Static)
status_label.update("🔄 Toggling enforcement mode...") status_label.update("🔄 Toggling enforcement mode...")
# Get API from app # Get API from app
api = self.app.api api = self.app.api
@@ -617,12 +617,12 @@ class AgentMoveOperations(Widget):
except Exception as e: except Exception as e:
logger.error(f"Error during toggle enforcement operation: {e}") logger.error(f"Error during toggle enforcement operation: {e}")
status_label.update(f"❌ Error: {str(e)}") status_label.update(f" Error: {str(e)}")
self.operation_in_progress = False self.operation_in_progress = False
return return
self.operation_in_progress = False self.operation_in_progress = False
status_label.update("✅ Operation complete!") status_label.update(" Operation complete!")
# Display results in the widget # Display results in the widget
self._display_results("Toggle Audit/Enforcement", successful, unsuccessful) self._display_results("Toggle Audit/Enforcement", successful, unsuccessful)
@@ -687,7 +687,7 @@ class AgentMoveOperations(Widget):
except Exception as e: except Exception as e:
logger.error(f"Error loading policies: {e}") logger.error(f"Error loading policies: {e}")
status_label.update(f"❌ Error: {str(e)}") status_label.update(f" Error: {str(e)}")
self.operation_in_progress = False self.operation_in_progress = False
self.selected_operation = "" self.selected_operation = ""
self.app.notify(f"Failed to load policies: {str(e)}", severity="error") self.app.notify(f"Failed to load policies: {str(e)}", severity="error")
@@ -722,7 +722,7 @@ class AgentMoveOperations(Widget):
) )
except Exception as e: except Exception as e:
logger.error(f"Failed to open execution history viewer: {e}") logger.error(f"Failed to open execution history viewer: {e}")
status_label.update(f" Error: {str(e)}") status_label.update(f"❌ Error: {str(e)}")
self.app.notify( self.app.notify(
f"Failed to open execution history: {str(e)}", severity="error" f"Failed to open execution history: {str(e)}", severity="error"
) )