Enhanced Quiet Finder
This commit is contained in:
+55
-25
@@ -237,14 +237,15 @@ def findAgents(url, device_input_str, return_dataframe):
|
||||
|
||||
#Filter the DataFrame using regex
|
||||
matched_df = df[df['hostname'].apply(lambda x: bool(regex.search(str(x))))]
|
||||
|
||||
#Export to CSV with timestamp
|
||||
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||
filename = f"agentsearch_{timestamp}.csv"
|
||||
matched_df.to_csv(f"device_search\\{filename}", index=False)
|
||||
|
||||
print(ct.colorText(f"\n✅ Matched devices exported to: device_search\\{filename}","green"))
|
||||
|
||||
if return_dataframe : return matched_df
|
||||
else:
|
||||
#Export to CSV with timestamp
|
||||
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||
filename = f"agentsearch_{timestamp}.csv"
|
||||
matched_df.to_csv(f"device_search\\{filename}", index=False)
|
||||
|
||||
print(ct.colorText(f"\n✅ Matched devices exported to: device_search\\{filename}","green"))
|
||||
|
||||
def promptForDevices():
|
||||
|
||||
@@ -351,53 +352,82 @@ def returnToEnforcement(url, device_df, policy_relationship_map, bad_publisher_l
|
||||
print(ct.colorText("Invalid choice. Please try again.", "red"))
|
||||
"""
|
||||
|
||||
|
||||
def findQuietAgents(url):
|
||||
|
||||
# Get policy selection and agent list
|
||||
choice, policynames, policyid = policyf.listPolicies(url)
|
||||
policy = policynames[choice]
|
||||
groupid = policyid[choice]
|
||||
agents = findGroupAgents(url,groupid)
|
||||
agents = findGroupAgents(url, groupid)
|
||||
|
||||
# Prompt user for history range
|
||||
while True:
|
||||
try:
|
||||
history_days = int(input("Enter the how many days in of history do you want to pull - select a number between 1 and 150: "))
|
||||
history_days = int(input("Enter how many days of history to pull (1–150): "))
|
||||
if 1 <= history_days <= 150:
|
||||
break
|
||||
else:
|
||||
print("Invalid input. Please enter a number between 1 and 150.")
|
||||
except ValueError:
|
||||
print("Invalid input. Please enter a valid integer.")
|
||||
|
||||
policy_exec_history = policyf.getPolicyInfo(url, policy, [1, 2, 6, 7], history_days)
|
||||
|
||||
# Count occurrences of each hostname in the executions dataframe
|
||||
while True:
|
||||
try:
|
||||
required_quiet = int(input("Enter how many days without an untrusted execution before these are considered ready for enforcement? (1–365): "))
|
||||
if 1 <= required_quiet <= 365:
|
||||
break
|
||||
else:
|
||||
print("Invalid input. Please enter a number between 1 and 365.")
|
||||
except ValueError:
|
||||
print("Invalid input. Please enter a valid integer.")
|
||||
|
||||
# Get policy execution history
|
||||
policy_exec_history = policyf.getPolicyInfo(url, policy, [1, 2, 6, 7], history_days, False)
|
||||
|
||||
# Convert 'datetime' column to timezone-aware datetime objects
|
||||
policy_exec_history['datetime'] = pd.to_datetime(policy_exec_history['datetime'], format='%Y-%m-%dT%H:%M:%SZ', utc=True)
|
||||
|
||||
# Get current UTC time
|
||||
now = datetime.datetime.now(datetime.timezone.utc)
|
||||
|
||||
# Calculate days ago
|
||||
policy_exec_history['days_ago'] = policy_exec_history['datetime'].apply(lambda dt: (now - dt).days)
|
||||
|
||||
# Count total executions per hostname
|
||||
hostname_counts = policy_exec_history['hostname'].value_counts()
|
||||
|
||||
# Map those counts to the hostnames in the first dataframe
|
||||
# Map execution counts to agents
|
||||
agents['execution_count'] = agents['hostname'].map(hostname_counts).fillna(0).astype(int)
|
||||
|
||||
# Find most recent execution per hostname
|
||||
most_recent_exec = policy_exec_history.sort_values(by='days_ago').drop_duplicates(subset='hostname', keep='first')
|
||||
|
||||
# Map most recent execution age to agents
|
||||
agents['days_since'] = agents['hostname'].map(most_recent_exec.set_index('hostname')['days_ago'])
|
||||
|
||||
#Check for enforcement readyness
|
||||
agents['required_quiet'] = required_quiet
|
||||
agents['enforce_ready'] = agents['days_since'].apply(
|
||||
lambda x: True if pd.isna(x) or x > required_quiet else False
|
||||
)
|
||||
|
||||
# Sort agents by execution count and hostname
|
||||
agents = agents.sort_values(by=['execution_count', 'hostname'], ascending=[True, True])
|
||||
|
||||
print(ct.colorText(f"Saving CSV to {policy}_agents_last_{history_days}_days.csv","green"))
|
||||
|
||||
# Save to CSV
|
||||
print(ct.colorText(f"Saving CSV to {policy}_agents_last_{history_days}_days.csv", "green"))
|
||||
agents.to_csv(f"{policy}_agents_last_{history_days}_days.csv", index=False)
|
||||
|
||||
|
||||
# Count hosts with execution_count == 0
|
||||
# Summary stats
|
||||
zero_count = (agents['execution_count'] == 0).sum()
|
||||
|
||||
# Total number of hosts
|
||||
total_hosts = len(agents)
|
||||
|
||||
# Calculate percentage
|
||||
zero_percentage = (zero_count / total_hosts) * 100
|
||||
|
||||
# Print results
|
||||
print(f"Number of hosts in policy : {total_hosts} ")
|
||||
print(f"Number of hosts in policy: {total_hosts}")
|
||||
print(f"Number of hosts with execution_count = 0: {zero_count}")
|
||||
print(f"Percentage of hosts with execution_count = 0: {zero_percentage:.2f}%")
|
||||
|
||||
|
||||
|
||||
def findGroupAgents(url, groupid):
|
||||
endpoint = url + '/v1/agent/find'
|
||||
payload = {
|
||||
|
||||
Reference in New Issue
Block a user