From 107bb744f55b8544f07424efdf5bc0512e17fe7d Mon Sep 17 00:00:00 2001
From: shloka-bhalgat-unskript
<110628398+shloka-bhalgat-unskript@users.noreply.github.com>
Date: Wed, 11 Oct 2023 10:01:08 +0530
Subject: [PATCH] Keycloak legos (#889)
---
Keycloak/__init__.py | 0
.../legos/keycloak_get_audit_report/README.md | 22 ++++++++
.../keycloak_get_audit_report/__init__.py | 0
.../keycloak_get_audit_report.json | 12 +++++
.../keycloak_get_audit_report.py | 53 +++++++++++++++++++
Keycloak/legos/keycloak_get_handle/README.md | 25 +++++++++
.../legos/keycloak_get_handle/__init__.py | 0
.../keycloak_get_handle.json | 11 ++++
.../keycloak_get_handle.py | 17 ++++++
.../keycloak_get_service_health/README.md | 22 ++++++++
.../keycloak_get_service_health/__init__.py | 0
.../keycloak_get_service_health.json | 16 ++++++
.../keycloak_get_service_health.py | 44 +++++++++++++++
13 files changed, 222 insertions(+)
create mode 100644 Keycloak/__init__.py
create mode 100644 Keycloak/legos/keycloak_get_audit_report/README.md
create mode 100644 Keycloak/legos/keycloak_get_audit_report/__init__.py
create mode 100644 Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.json
create mode 100644 Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.py
create mode 100644 Keycloak/legos/keycloak_get_handle/README.md
create mode 100644 Keycloak/legos/keycloak_get_handle/__init__.py
create mode 100644 Keycloak/legos/keycloak_get_handle/keycloak_get_handle.json
create mode 100644 Keycloak/legos/keycloak_get_handle/keycloak_get_handle.py
create mode 100644 Keycloak/legos/keycloak_get_service_health/README.md
create mode 100644 Keycloak/legos/keycloak_get_service_health/__init__.py
create mode 100644 Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.json
create mode 100644 Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.py
diff --git a/Keycloak/__init__.py b/Keycloak/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/Keycloak/legos/keycloak_get_audit_report/README.md b/Keycloak/legos/keycloak_get_audit_report/README.md
new file mode 100644
index 000000000..ae099f6bf
--- /dev/null
+++ b/Keycloak/legos/keycloak_get_audit_report/README.md
@@ -0,0 +1,22 @@
+[]
+(https://unskript.com/assets/favicon.png)
+
Get Keycloak audit report
+
+## Description
+Fetches the audit events from Keycloak.
+
+## Lego Details
+ keycloak_get_audit_report(handle):
+ handle: Handle object containing the KeycloakAdmin 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/Keycloak/legos/keycloak_get_audit_report/__init__.py b/Keycloak/legos/keycloak_get_audit_report/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.json b/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.json
new file mode 100644
index 000000000..93a3a6e74
--- /dev/null
+++ b/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.json
@@ -0,0 +1,12 @@
+{
+ "action_title": "Get Keycloak audit report",
+ "action_description": "Fetches the audit events from Keycloak.",
+ "action_type": "LEGO_TYPE_KEYCLOAK",
+ "action_entry_function": "keycloak_get_audit_report",
+ "action_needs_credential": true,
+ "action_output_type": "ACTION_OUTPUT_TYPE_LIST",
+ "action_is_check": false,
+ "action_supports_iteration": true,
+ "action_supports_poll": true,
+ "action_categories":["CATEGORY_TYPE_SRE","CATEGORY_TYPE_KEYCLOAK"]
+ }
\ No newline at end of file
diff --git a/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.py b/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.py
new file mode 100644
index 000000000..939654333
--- /dev/null
+++ b/Keycloak/legos/keycloak_get_audit_report/keycloak_get_audit_report.py
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 2023 unSkript.com
+# All rights reserved.
+#
+from typing import List
+from tabulate import tabulate
+from pydantic import BaseModel
+
+
+class InputSchema(BaseModel):
+ pass
+
+
+def keycloak_get_audit_report_printer(output):
+ if not output:
+ print("No audit events found.")
+ return
+
+ # Extract relevant event data for tabulation
+ table_data = []
+ for event in output:
+ table_data.append({
+ "Time": event['time'],
+ "Type": event['type'],
+ "User ID": event['userId'],
+ "Client ID": event['clientId'],
+ "IP Address": event['ipAddress'],
+ "Error": event.get('error', '')
+ })
+
+ # Convert list of dictionaries to tabulated format
+ headers = ["Time", "Type", "User ID", "Client ID", "IP Address", "Error"]
+ print(tabulate(table_data, headers=headers, tablefmt="grid"))
+
+
+def keycloak_get_audit_report(handle) -> List:
+ """
+ keycloak_get_audit_report fetches the audit events from Keycloak.
+
+ :type handle: KeycloakAdmin
+ :param handle: Handle containing the KeycloakAdmin instance.
+
+ :rtype: List of dictionaries representing the audit events.
+ """
+ try:
+ # Fetch the events
+ events = handle.get_events()
+ return events if events else []
+
+ except Exception as e:
+ raise e
+
+
diff --git a/Keycloak/legos/keycloak_get_handle/README.md b/Keycloak/legos/keycloak_get_handle/README.md
new file mode 100644
index 000000000..2e4556786
--- /dev/null
+++ b/Keycloak/legos/keycloak_get_handle/README.md
@@ -0,0 +1,25 @@
+[](https://unskript.com/assets/favicon.png)
+Get Keycloak Handle
+
+
+
+## Description
+This Lego Get Keycloak Handle.
+
+
+## Lego Details
+
+ keycloak_get_handle(handle: object)
+
+ handle: Object of type unSkript Keycloak 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/Keycloak/legos/keycloak_get_handle/__init__.py b/Keycloak/legos/keycloak_get_handle/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.json b/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.json
new file mode 100644
index 000000000..b1e5942c3
--- /dev/null
+++ b/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.json
@@ -0,0 +1,11 @@
+{
+ "action_title": "Keycloak Get Handle",
+ "action_description": "Get Keycloak Handle",
+ "action_type": "LEGO_TYPE_KEYCLOAK",
+ "action_entry_function": "keycloak_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/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.py b/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.py
new file mode 100644
index 000000000..e9f21a1a9
--- /dev/null
+++ b/Keycloak/legos/keycloak_get_handle/keycloak_get_handle.py
@@ -0,0 +1,17 @@
+##
+## Copyright (c) 2023 unSkript, Inc
+## All rights reserved.
+##
+from pydantic import BaseModel
+
+
+class InputSchema(BaseModel):
+ pass
+
+
+def keycloak_get_handle(handle):
+ """keycloak_get_handle returns the Keycloak handle.
+
+ :rtype: Keycloak handle.
+ """
+ return handle
diff --git a/Keycloak/legos/keycloak_get_service_health/README.md b/Keycloak/legos/keycloak_get_service_health/README.md
new file mode 100644
index 000000000..724039c95
--- /dev/null
+++ b/Keycloak/legos/keycloak_get_service_health/README.md
@@ -0,0 +1,22 @@
+[]
+(https://unskript.com/assets/favicon.png)
+Get Keycloak service health
+
+## Description
+Fetches the health of the Keycloak service by trying to list available realms.
+
+## Lego Details
+ keycloak_get_service_health fetches the health of the Keycloak service by trying to list available realms.
+ handle: Handle containing the KeycloakAdmin 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/Keycloak/legos/keycloak_get_service_health/__init__.py b/Keycloak/legos/keycloak_get_service_health/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.json b/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.json
new file mode 100644
index 000000000..8bd9c9344
--- /dev/null
+++ b/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.json
@@ -0,0 +1,16 @@
+{
+ "action_title": "Get Keycloak service health",
+ "action_description": "Fetches the health of the Keycloak service by trying to list available realms.",
+ "action_type": "LEGO_TYPE_KEYCLOAK",
+ "action_entry_function": "keycloak_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_SRE","CATEGORY_TYPE_KEYCLOAK"]
+ }
\ No newline at end of file
diff --git a/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.py b/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.py
new file mode 100644
index 000000000..edf85be34
--- /dev/null
+++ b/Keycloak/legos/keycloak_get_service_health/keycloak_get_service_health.py
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2023 unSkript.com
+# All rights reserved.
+#
+
+from typing import Tuple
+from pydantic import BaseModel
+
+
+class InputSchema(BaseModel):
+ pass
+
+def keycloak_get_service_health(handle) -> Tuple:
+ """
+ keycloak_get_service_health fetches the health of the Keycloak service by trying to list available realms.
+
+ :type handle: object
+ :param handle: Handle containing the KeycloakAdmin instance.
+
+ :rtype: Tuple indicating if the service is healthy and a list of available realms (or None if healthy).
+ """
+ try:
+ realms = handle.get_realms()
+ available_realms = [realm["realm"] for realm in realms]
+
+ if not available_realms:
+ return (False, available_realms)
+
+ return (True, None)
+
+ except Exception as e:
+ raise e
+
+def keycloak_get_service_health_printer(output):
+ is_healthy, realms = output
+
+ if is_healthy:
+ print("Keycloak Service is Healthy.")
+ else:
+ print("Keycloak Service is Unhealthy.")
+ if realms:
+ print("\nUnavailable Realms:")
+ for realm in realms:
+ print(f" - {realm}")