diff --git a/SSH/legos/ssh_get_hosts_with_low_disk_latency/1.png b/SSH/legos/ssh_get_hosts_with_low_disk_latency/1.png new file mode 100644 index 000000000..00f1c59d6 Binary files /dev/null and b/SSH/legos/ssh_get_hosts_with_low_disk_latency/1.png differ diff --git a/SSH/legos/ssh_get_hosts_with_low_disk_latency/README.md b/SSH/legos/ssh_get_hosts_with_low_disk_latency/README.md new file mode 100644 index 000000000..cabc9b772 --- /dev/null +++ b/SSH/legos/ssh_get_hosts_with_low_disk_latency/README.md @@ -0,0 +1,24 @@ +[] +(https://unskript.com/assets/favicon.png) +

Get hosts with low disk latency

+ +## Description +This action checks the disk latency on the provided hosts by running a disk write command and measuring the time taken. If the time taken exceeds a given threshold, the host is flagged as having potential latency issues. + +## Lego Details + ssh_get_hosts_with_low_disk_latency(handle, hosts: list, threshold: int = 5) + handle: Object of type unSkript SSH Connector. + hosts: List of hosts to connect to. + threshold: Time threshold in seconds to flag a host for potential latency issues. + + +## Lego Input +This Lego takes inputs handle, hosts, threshold. + +## Lego Output +Here is a sample output. + + +## See it in Action + +You can see this Lego in action following this link [unSkript Live](https://us.app.unskript.io) \ No newline at end of file diff --git a/SSH/legos/ssh_get_hosts_with_low_disk_latency/__init__.py b/SSH/legos/ssh_get_hosts_with_low_disk_latency/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/SSH/legos/ssh_get_hosts_with_low_disk_latency/ssh_get_hosts_with_low_disk_latency.json b/SSH/legos/ssh_get_hosts_with_low_disk_latency/ssh_get_hosts_with_low_disk_latency.json new file mode 100644 index 000000000..b9285054a --- /dev/null +++ b/SSH/legos/ssh_get_hosts_with_low_disk_latency/ssh_get_hosts_with_low_disk_latency.json @@ -0,0 +1,15 @@ +{ + "action_title": "Get hosts with low disk latency ", + "action_description": "This action checks the disk latency on the provided hosts by running a disk write command and measuring the time taken. If the time taken exceeds a given threshold, the host is flagged as having potential latency issues.", + "action_type": "LEGO_TYPE_SSH", + "action_entry_function": "ssh_get_hosts_with_low_disk_latency", + "action_needs_credential": true, + "action_output_type": "ACTION_OUTPUT_TYPE_LIST", + "action_is_check": true, + "action_next_hop": [ + "" + ], + "action_next_hop_parameter_mapping": {}, + "action_supports_iteration": true, + "action_supports_poll": true +} \ No newline at end of file diff --git a/SSH/legos/ssh_get_hosts_with_low_disk_latency/ssh_get_hosts_with_low_disk_latency.py b/SSH/legos/ssh_get_hosts_with_low_disk_latency/ssh_get_hosts_with_low_disk_latency.py new file mode 100644 index 000000000..a970f8c4c --- /dev/null +++ b/SSH/legos/ssh_get_hosts_with_low_disk_latency/ssh_get_hosts_with_low_disk_latency.py @@ -0,0 +1,91 @@ +## +# Copyright (c) 2023 unSkript, Inc +# All rights reserved. +## +from typing import Tuple, Optional +from pydantic import BaseModel, Field +from unskript.legos.ssh.ssh_execute_remote_command.ssh_execute_remote_command import ssh_execute_remote_command + + +class InputSchema(BaseModel): + hosts: list = Field( + ..., + description='List of hosts to connect to. For eg. ["host1", "host2"].', + title='Lis of Hosts', + ) + threshold: Optional[float] = Field( + 10, + description='Time threshold in seconds to flag a host for potential latency issues.', + title='Threshold (in seconds)', + ) + + +def ssh_get_hosts_with_low_disk_latency_printer(output): + if not output: + print("No issues found.") + return + + status, problematic_hosts = output + if not status: + print("Hosts with potential disk latency issues:", ', '.join(problematic_hosts)) + else: + print("No latency issues found on any hosts.") + +def ssh_get_hosts_with_low_disk_latency(handle, hosts: list, threshold: int = 5) -> Tuple: + """ + ssh_get_hosts_with_low_disk_latency Checks the disk latency on the provided hosts by running a disk write command and + measuring the time taken. If the time taken exceeds a given threshold, the host is + flagged as having potential latency issues. + + :type handle: SSH Client object + :param handle: The SSH client. + + :type hosts: list + :param hosts: List of hosts to connect to. + + :type threshold: float + :param threshold: Time threshold in seconds to flag a host for potential latency issues. + + :return: Status and the hosts with potential latency issues if any. + """ + print("Starting the disk latency check...") + + latency_command = "/usr/bin/time -p dd if=/dev/zero of=~/test.png bs=8192 count=10240 oflag=direct 2>&1" + outputs = ssh_execute_remote_command(handle, hosts, latency_command) + + # Cleanup: Remove the created test file + print("Cleaning up resources...") + cleanup_command = "rm ~/test.png" + ssh_execute_remote_command(handle, hosts, cleanup_command) + + hosts_with_issues = [] + + for host, output in outputs.items(): + if not output.strip(): + print(f"Command execution failed or returned empty output on host {host}.") + continue + + for line in output.splitlines(): + if line.startswith("real"): + time_line = line + break + else: + print(f"Couldn't find 'real' time in output for host {host}.") + continue + + # Parse the time and check against the threshold + try: + total_seconds = float(time_line.split()[1]) + + if total_seconds > threshold: + hosts_with_issues.append(host) + except Exception as e: + raise e + + if hosts_with_issues: + return (False, hosts_with_issues) + return (True, None) + + + + diff --git a/Vault/__init__.py b/Vault/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Vault/legos/__init__.py b/Vault/legos/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Vault/legos/vault_get_handle/README.md b/Vault/legos/vault_get_handle/README.md new file mode 100644 index 000000000..70f197df1 --- /dev/null +++ b/Vault/legos/vault_get_handle/README.md @@ -0,0 +1,25 @@ +[](https://unskript.com/assets/favicon.png) +

Get Vault Handle

+ +
+ +## Description +This Lego Get Vault Handle. + + +## Lego Details + + vault_get_handle(handle: object) + + handle: Object of type unSkript Vault Connector + +## Lego Input +This Lego take one input handle. + +## Lego Output +Here is a sample output. + + +## See it in Action + +You can see this Lego in action following this link [unSkript Live](https://us.app.unskript.io) \ No newline at end of file diff --git a/Vault/legos/vault_get_handle/__init__.py b/Vault/legos/vault_get_handle/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Vault/legos/vault_get_handle/vault_get_handle.json b/Vault/legos/vault_get_handle/vault_get_handle.json new file mode 100644 index 000000000..a1af9ad00 --- /dev/null +++ b/Vault/legos/vault_get_handle/vault_get_handle.json @@ -0,0 +1,11 @@ +{ + "action_title": "Vault Get Handle", + "action_description": "Get Vault Handle", + "action_type": "LEGO_TYPE_VAULT", + "action_entry_function": "vault_get_handle", + "action_needs_credential": true, + "action_supports_poll": false, + "action_supports_iteration": false, + "action_output_type": "ACTION_OUTPUT_TYPE_LIST" +} + \ No newline at end of file diff --git a/Vault/legos/vault_get_handle/vault_get_handle.py b/Vault/legos/vault_get_handle/vault_get_handle.py new file mode 100644 index 000000000..edf9df5be --- /dev/null +++ b/Vault/legos/vault_get_handle/vault_get_handle.py @@ -0,0 +1,17 @@ +## +## Copyright (c) 2023 unSkript, Inc +## All rights reserved. +## +from pydantic import BaseModel + + +class InputSchema(BaseModel): + pass + + +def vault_get_handle(handle): + """vault_get_handle returns the Vault handle. + + :rtype: Vault handle. + """ + return handle diff --git a/Vault/legos/vault_get_service_health/README.md b/Vault/legos/vault_get_service_health/README.md new file mode 100644 index 000000000..849383475 --- /dev/null +++ b/Vault/legos/vault_get_service_health/README.md @@ -0,0 +1,22 @@ +[] +(https://unskript.com/assets/favicon.png) +

Get Vault service health

+ +## Description +Fetches the health of the Vault service by using hvac's sys/health call. + +## Lego Details + vault_get_service_health fetches the health of the Vault service by using hvac's sys/health call. + handle: Handle containing the Vault instance. + + +## Lego Input +This Lego takes inputs handle. + +## Lego Output +Here is a sample output. + + +## See it in Action + +You can see this Lego in action following this link [unSkript Live](https://us.app.unskript.io) \ No newline at end of file diff --git a/Vault/legos/vault_get_service_health/__init__.py b/Vault/legos/vault_get_service_health/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Vault/legos/vault_get_service_health/vault_get_service_health.json b/Vault/legos/vault_get_service_health/vault_get_service_health.json new file mode 100644 index 000000000..8cc0cbab2 --- /dev/null +++ b/Vault/legos/vault_get_service_health/vault_get_service_health.json @@ -0,0 +1,16 @@ +{ + "action_title": "Get Vault service health", + "action_description": "Fetches the health of the Vault service by using hvac's sys/health call.", + "action_type": "LEGO_TYPE_VAULT", + "action_entry_function": "vault_get_service_health", + "action_needs_credential": true, + "action_output_type": "ACTION_OUTPUT_TYPE_LIST", + "action_is_check": true, + "action_next_hop": [ + "" + ], + "action_next_hop_parameter_mapping": {}, + "action_supports_iteration": true, + "action_supports_poll": true, + "action_categories":["CATEGORY_TYPE_SECOPS","LEGO_TYPE_VAULT"] + } \ No newline at end of file diff --git a/Vault/legos/vault_get_service_health/vault_get_service_health.py b/Vault/legos/vault_get_service_health/vault_get_service_health.py new file mode 100644 index 000000000..8ff588b9b --- /dev/null +++ b/Vault/legos/vault_get_service_health/vault_get_service_health.py @@ -0,0 +1,48 @@ +from typing import Tuple +import hvac +from pydantic import BaseModel + + +class InputSchema(BaseModel): + pass + +def vault_get_service_health_printer(output): + is_healthy, errors = output + + if is_healthy: + print("Vault Service is Healthy.") + else: + print("Vault Service is Unhealthy.") + if errors: + print("\nErrors:") + for error in errors: + print(f" - {error}") + +def vault_get_service_health(handle) -> Tuple: + """ + vault_get_service_health fetches the health of the Vault service by using hvac's sys/health call. + + :type handle: object + :param handle: Handle containing the Vault instance. + + :rtype: Tuple indicating if the service is healthy and an error message (or None if healthy). + """ + try: + health_data = handle.sys.read_health_status(method='GET') + + # Health check is successful if Vault is initialized, not in standby, and unsealed + if health_data["initialized"] and not health_data["standby"] and not health_data["sealed"]: + return (True, None) + else: + error_msg = [] + if not health_data["initialized"]: + error_msg.append("Vault is not initialized.") + if health_data["standby"]: + error_msg.append("Vault is in standby mode.") + if health_data["sealed"]: + error_msg.append("Vault is sealed.") + return (False, error_msg) + + except Exception as e: + raise e +