kailash 0.6.3__py3-none-any.whl → 0.6.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kailash/__init__.py +3 -3
- kailash/api/custom_nodes_secure.py +3 -3
- kailash/api/gateway.py +1 -1
- kailash/api/studio.py +2 -3
- kailash/api/workflow_api.py +3 -4
- kailash/core/resilience/bulkhead.py +460 -0
- kailash/core/resilience/circuit_breaker.py +92 -10
- kailash/edge/discovery.py +86 -0
- kailash/mcp_server/__init__.py +309 -33
- kailash/mcp_server/advanced_features.py +1022 -0
- kailash/mcp_server/ai_registry_server.py +27 -2
- kailash/mcp_server/auth.py +789 -0
- kailash/mcp_server/client.py +645 -378
- kailash/mcp_server/discovery.py +1593 -0
- kailash/mcp_server/errors.py +673 -0
- kailash/mcp_server/oauth.py +1727 -0
- kailash/mcp_server/protocol.py +1126 -0
- kailash/mcp_server/registry_integration.py +587 -0
- kailash/mcp_server/server.py +1213 -98
- kailash/mcp_server/transports.py +1169 -0
- kailash/mcp_server/utils/__init__.py +6 -1
- kailash/mcp_server/utils/cache.py +250 -7
- kailash/middleware/auth/auth_manager.py +3 -3
- kailash/middleware/communication/api_gateway.py +2 -9
- kailash/middleware/communication/realtime.py +1 -1
- kailash/middleware/mcp/enhanced_server.py +1 -1
- kailash/nodes/__init__.py +2 -0
- kailash/nodes/admin/audit_log.py +6 -6
- kailash/nodes/admin/permission_check.py +8 -8
- kailash/nodes/admin/role_management.py +32 -28
- kailash/nodes/admin/schema.sql +6 -1
- kailash/nodes/admin/schema_manager.py +13 -13
- kailash/nodes/admin/security_event.py +16 -20
- kailash/nodes/admin/tenant_isolation.py +3 -3
- kailash/nodes/admin/transaction_utils.py +3 -3
- kailash/nodes/admin/user_management.py +21 -22
- kailash/nodes/ai/a2a.py +11 -11
- kailash/nodes/ai/ai_providers.py +9 -12
- kailash/nodes/ai/embedding_generator.py +13 -14
- kailash/nodes/ai/intelligent_agent_orchestrator.py +19 -19
- kailash/nodes/ai/iterative_llm_agent.py +2 -2
- kailash/nodes/ai/llm_agent.py +210 -33
- kailash/nodes/ai/self_organizing.py +2 -2
- kailash/nodes/alerts/discord.py +4 -4
- kailash/nodes/api/graphql.py +6 -6
- kailash/nodes/api/http.py +12 -17
- kailash/nodes/api/rate_limiting.py +4 -4
- kailash/nodes/api/rest.py +15 -15
- kailash/nodes/auth/mfa.py +3 -4
- kailash/nodes/auth/risk_assessment.py +2 -2
- kailash/nodes/auth/session_management.py +5 -5
- kailash/nodes/auth/sso.py +143 -0
- kailash/nodes/base.py +6 -2
- kailash/nodes/base_async.py +16 -2
- kailash/nodes/base_with_acl.py +2 -2
- kailash/nodes/cache/__init__.py +9 -0
- kailash/nodes/cache/cache.py +1172 -0
- kailash/nodes/cache/cache_invalidation.py +870 -0
- kailash/nodes/cache/redis_pool_manager.py +595 -0
- kailash/nodes/code/async_python.py +2 -1
- kailash/nodes/code/python.py +196 -35
- kailash/nodes/compliance/data_retention.py +6 -6
- kailash/nodes/compliance/gdpr.py +5 -5
- kailash/nodes/data/__init__.py +10 -0
- kailash/nodes/data/optimistic_locking.py +906 -0
- kailash/nodes/data/readers.py +8 -8
- kailash/nodes/data/redis.py +349 -0
- kailash/nodes/data/sql.py +314 -3
- kailash/nodes/data/streaming.py +21 -0
- kailash/nodes/enterprise/__init__.py +8 -0
- kailash/nodes/enterprise/audit_logger.py +285 -0
- kailash/nodes/enterprise/batch_processor.py +22 -3
- kailash/nodes/enterprise/data_lineage.py +1 -1
- kailash/nodes/enterprise/mcp_executor.py +205 -0
- kailash/nodes/enterprise/service_discovery.py +150 -0
- kailash/nodes/enterprise/tenant_assignment.py +108 -0
- kailash/nodes/logic/async_operations.py +2 -2
- kailash/nodes/logic/convergence.py +1 -1
- kailash/nodes/logic/operations.py +1 -1
- kailash/nodes/monitoring/__init__.py +11 -1
- kailash/nodes/monitoring/health_check.py +456 -0
- kailash/nodes/monitoring/log_processor.py +817 -0
- kailash/nodes/monitoring/metrics_collector.py +627 -0
- kailash/nodes/monitoring/performance_benchmark.py +137 -11
- kailash/nodes/rag/advanced.py +7 -7
- kailash/nodes/rag/agentic.py +49 -2
- kailash/nodes/rag/conversational.py +3 -3
- kailash/nodes/rag/evaluation.py +3 -3
- kailash/nodes/rag/federated.py +3 -3
- kailash/nodes/rag/graph.py +3 -3
- kailash/nodes/rag/multimodal.py +3 -3
- kailash/nodes/rag/optimized.py +5 -5
- kailash/nodes/rag/privacy.py +3 -3
- kailash/nodes/rag/query_processing.py +6 -6
- kailash/nodes/rag/realtime.py +1 -1
- kailash/nodes/rag/registry.py +2 -6
- kailash/nodes/rag/router.py +1 -1
- kailash/nodes/rag/similarity.py +7 -7
- kailash/nodes/rag/strategies.py +4 -4
- kailash/nodes/security/abac_evaluator.py +6 -6
- kailash/nodes/security/behavior_analysis.py +5 -6
- kailash/nodes/security/credential_manager.py +1 -1
- kailash/nodes/security/rotating_credentials.py +11 -11
- kailash/nodes/security/threat_detection.py +8 -8
- kailash/nodes/testing/credential_testing.py +2 -2
- kailash/nodes/transform/processors.py +5 -5
- kailash/runtime/local.py +162 -14
- kailash/runtime/parameter_injection.py +425 -0
- kailash/runtime/parameter_injector.py +657 -0
- kailash/runtime/testing.py +2 -2
- kailash/testing/fixtures.py +2 -2
- kailash/workflow/builder.py +99 -18
- kailash/workflow/builder_improvements.py +207 -0
- kailash/workflow/input_handling.py +170 -0
- {kailash-0.6.3.dist-info → kailash-0.6.4.dist-info}/METADATA +22 -9
- {kailash-0.6.3.dist-info → kailash-0.6.4.dist-info}/RECORD +120 -94
- {kailash-0.6.3.dist-info → kailash-0.6.4.dist-info}/WHEEL +0 -0
- {kailash-0.6.3.dist-info → kailash-0.6.4.dist-info}/entry_points.txt +0 -0
- {kailash-0.6.3.dist-info → kailash-0.6.4.dist-info}/licenses/LICENSE +0 -0
- {kailash-0.6.3.dist-info → kailash-0.6.4.dist-info}/top_level.txt +0 -0
@@ -171,7 +171,7 @@ class RoleManagementNode(Node):
|
|
171
171
|
... }
|
172
172
|
... }
|
173
173
|
... )
|
174
|
-
>>> result = node.
|
174
|
+
>>> result = node.execute()
|
175
175
|
>>> role_id = result["role"]["role_id"]
|
176
176
|
|
177
177
|
>>> # Bulk user assignment
|
@@ -181,7 +181,7 @@ class RoleManagementNode(Node):
|
|
181
181
|
... user_ids=["user1", "user2", "user3"],
|
182
182
|
... validate_hierarchy=True
|
183
183
|
... )
|
184
|
-
>>> result = node.
|
184
|
+
>>> result = node.execute()
|
185
185
|
>>> assigned_count = result["stats"]["assigned"]
|
186
186
|
"""
|
187
187
|
|
@@ -500,7 +500,7 @@ class RoleManagementNode(Node):
|
|
500
500
|
"""
|
501
501
|
|
502
502
|
# Execute database insert
|
503
|
-
db_result = self._db_node.
|
503
|
+
db_result = self._db_node.execute(
|
504
504
|
query=insert_query,
|
505
505
|
parameters=[
|
506
506
|
role_record["role_id"],
|
@@ -563,7 +563,7 @@ class RoleManagementNode(Node):
|
|
563
563
|
WHERE user_id = $1 AND role_id = $2 AND tenant_id = $3 AND is_active = true
|
564
564
|
"""
|
565
565
|
|
566
|
-
existing = self._db_node.
|
566
|
+
existing = self._db_node.execute(
|
567
567
|
query=existing_query,
|
568
568
|
parameters=[user_id, role_id, tenant_id],
|
569
569
|
result_format="dict",
|
@@ -594,7 +594,7 @@ class RoleManagementNode(Node):
|
|
594
594
|
is_active = true
|
595
595
|
"""
|
596
596
|
|
597
|
-
db_result = self._db_node.
|
597
|
+
db_result = self._db_node.execute(
|
598
598
|
query=insert_query,
|
599
599
|
parameters=[
|
600
600
|
user_id,
|
@@ -740,7 +740,9 @@ class RoleManagementNode(Node):
|
|
740
740
|
|
741
741
|
params = [tenant_id] + list(parent_roles)
|
742
742
|
|
743
|
-
result = self._db_node.
|
743
|
+
result = self._db_node.execute(
|
744
|
+
query=query, parameters=params, result_format="dict"
|
745
|
+
)
|
744
746
|
existing_roles = {row["role_id"] for row in result.get("data", [])}
|
745
747
|
|
746
748
|
missing_roles = parent_roles - existing_roles
|
@@ -798,7 +800,7 @@ class RoleManagementNode(Node):
|
|
798
800
|
query += " AND role_id != $2"
|
799
801
|
params.append(exclude_role)
|
800
802
|
|
801
|
-
result = self._db_node.
|
803
|
+
result = self._db_node.execute(query=query, parameters=params, fetch_mode="all")
|
802
804
|
roles_data = result.get("data", [])
|
803
805
|
|
804
806
|
# Convert to hierarchy dict
|
@@ -841,7 +843,7 @@ class RoleManagementNode(Node):
|
|
841
843
|
WHERE role_id = $1 AND tenant_id = $2
|
842
844
|
"""
|
843
845
|
|
844
|
-
result = self._db_node.
|
846
|
+
result = self._db_node.execute(
|
845
847
|
query=query, parameters=[role_id, tenant_id], result_format="dict"
|
846
848
|
)
|
847
849
|
data = result.get("data", [])
|
@@ -865,7 +867,7 @@ class RoleManagementNode(Node):
|
|
865
867
|
WHERE role_id = $1 AND tenant_id = $2
|
866
868
|
"""
|
867
869
|
|
868
|
-
result = self._db_node.
|
870
|
+
result = self._db_node.execute(
|
869
871
|
query=get_query,
|
870
872
|
parameters=[parent_role_id, tenant_id],
|
871
873
|
result_format="dict",
|
@@ -893,7 +895,7 @@ class RoleManagementNode(Node):
|
|
893
895
|
WHERE role_id = $3 AND tenant_id = $4
|
894
896
|
"""
|
895
897
|
|
896
|
-
self._db_node.
|
898
|
+
self._db_node.execute(
|
897
899
|
query=update_query,
|
898
900
|
parameters=[
|
899
901
|
json.dumps(current_child_roles),
|
@@ -964,7 +966,7 @@ class RoleManagementNode(Node):
|
|
964
966
|
RETURNING role_id, name, description, permissions, parent_roles, attributes, is_active, updated_at
|
965
967
|
"""
|
966
968
|
|
967
|
-
result = self._db_node.
|
969
|
+
result = self._db_node.execute(
|
968
970
|
query=update_query, parameters=params, fetch_mode="one"
|
969
971
|
)
|
970
972
|
updated_role = result.get("data", [])
|
@@ -1027,7 +1029,7 @@ class RoleManagementNode(Node):
|
|
1027
1029
|
) AND tenant_id = $2 AND is_active = true
|
1028
1030
|
"""
|
1029
1031
|
|
1030
|
-
child_result = self._db_node.
|
1032
|
+
child_result = self._db_node.execute(
|
1031
1033
|
query=child_roles_query,
|
1032
1034
|
parameters=[role_id, tenant_id],
|
1033
1035
|
fetch_mode="all",
|
@@ -1046,7 +1048,7 @@ class RoleManagementNode(Node):
|
|
1046
1048
|
WHERE role_id = $1 AND tenant_id = $2
|
1047
1049
|
"""
|
1048
1050
|
|
1049
|
-
user_result = self._db_node.
|
1051
|
+
user_result = self._db_node.execute(
|
1050
1052
|
query=user_assignments_query,
|
1051
1053
|
parameters=[role_id, tenant_id],
|
1052
1054
|
fetch_mode="one",
|
@@ -1067,7 +1069,7 @@ class RoleManagementNode(Node):
|
|
1067
1069
|
DELETE FROM user_role_assignments WHERE role_id = $1 AND tenant_id = $2
|
1068
1070
|
"""
|
1069
1071
|
|
1070
|
-
self._db_node.
|
1072
|
+
self._db_node.execute(
|
1071
1073
|
query=delete_assignments_query, parameters=[role_id, tenant_id]
|
1072
1074
|
)
|
1073
1075
|
|
@@ -1092,7 +1094,7 @@ class RoleManagementNode(Node):
|
|
1092
1094
|
) AND tenant_id = $3
|
1093
1095
|
"""
|
1094
1096
|
|
1095
|
-
self._db_node.
|
1097
|
+
self._db_node.execute(
|
1096
1098
|
query=update_children_query,
|
1097
1099
|
parameters=[role_id, datetime.now(UTC), tenant_id],
|
1098
1100
|
)
|
@@ -1102,7 +1104,7 @@ class RoleManagementNode(Node):
|
|
1102
1104
|
DELETE FROM roles WHERE role_id = $1 AND tenant_id = $2
|
1103
1105
|
"""
|
1104
1106
|
|
1105
|
-
self._db_node.
|
1107
|
+
self._db_node.execute(query=delete_query, parameters=[role_id, tenant_id])
|
1106
1108
|
|
1107
1109
|
return {
|
1108
1110
|
"result": {
|
@@ -1170,7 +1172,7 @@ class RoleManagementNode(Node):
|
|
1170
1172
|
base_query += f" OFFSET ${param_count}"
|
1171
1173
|
params.append(offset)
|
1172
1174
|
|
1173
|
-
result = self._db_node.
|
1175
|
+
result = self._db_node.execute(
|
1174
1176
|
query=base_query, parameters=params, fetch_mode="all"
|
1175
1177
|
)
|
1176
1178
|
roles_data = result.get("data", [])
|
@@ -1182,7 +1184,7 @@ class RoleManagementNode(Node):
|
|
1182
1184
|
WHERE {' AND '.join(where_conditions)}
|
1183
1185
|
"""
|
1184
1186
|
|
1185
|
-
count_result = self._db_node.
|
1187
|
+
count_result = self._db_node.execute(
|
1186
1188
|
query=count_query,
|
1187
1189
|
parameters=(
|
1188
1190
|
params[: param_count - 2] if limit > 0 else params
|
@@ -1309,7 +1311,7 @@ class RoleManagementNode(Node):
|
|
1309
1311
|
ORDER BY ur.assigned_at DESC
|
1310
1312
|
"""
|
1311
1313
|
|
1312
|
-
users_result = self._db_node.
|
1314
|
+
users_result = self._db_node.execute(
|
1313
1315
|
query=users_query, parameters=[role_id, tenant_id], fetch_mode="all"
|
1314
1316
|
)
|
1315
1317
|
users_data = users_result.get("data", [])
|
@@ -1349,7 +1351,7 @@ class RoleManagementNode(Node):
|
|
1349
1351
|
WHERE user_id = $1 AND role_id = $2 AND tenant_id = $3
|
1350
1352
|
"""
|
1351
1353
|
|
1352
|
-
existing = self._db_node.
|
1354
|
+
existing = self._db_node.execute(
|
1353
1355
|
query=check_query,
|
1354
1356
|
parameters=[user_id, role_id, tenant_id],
|
1355
1357
|
fetch_mode="one",
|
@@ -1377,7 +1379,9 @@ class RoleManagementNode(Node):
|
|
1377
1379
|
WHERE user_id = $1 AND role_id = $2 AND tenant_id = $3
|
1378
1380
|
"""
|
1379
1381
|
|
1380
|
-
self._db_node.
|
1382
|
+
self._db_node.execute(
|
1383
|
+
query=delete_query, parameters=[user_id, role_id, tenant_id]
|
1384
|
+
)
|
1381
1385
|
|
1382
1386
|
return {
|
1383
1387
|
"result": {
|
@@ -1436,7 +1440,7 @@ class RoleManagementNode(Node):
|
|
1436
1440
|
RETURNING permissions
|
1437
1441
|
"""
|
1438
1442
|
|
1439
|
-
result = self._db_node.
|
1443
|
+
result = self._db_node.execute(
|
1440
1444
|
query=update_query,
|
1441
1445
|
parameters=[
|
1442
1446
|
json.dumps(new_permissions),
|
@@ -1496,7 +1500,7 @@ class RoleManagementNode(Node):
|
|
1496
1500
|
RETURNING permissions
|
1497
1501
|
"""
|
1498
1502
|
|
1499
|
-
result = self._db_node.
|
1503
|
+
result = self._db_node.execute(
|
1500
1504
|
query=update_query,
|
1501
1505
|
parameters=[
|
1502
1506
|
json.dumps(new_permissions),
|
@@ -1600,7 +1604,7 @@ class RoleManagementNode(Node):
|
|
1600
1604
|
|
1601
1605
|
roles_query += " ORDER BY ur.assigned_at DESC"
|
1602
1606
|
|
1603
|
-
result = self._db_node.
|
1607
|
+
result = self._db_node.execute(
|
1604
1608
|
query=roles_query, parameters=params, fetch_mode="all"
|
1605
1609
|
)
|
1606
1610
|
roles_data = result.get("data", [])
|
@@ -1699,7 +1703,7 @@ class RoleManagementNode(Node):
|
|
1699
1703
|
LIMIT $3 OFFSET $4
|
1700
1704
|
"""
|
1701
1705
|
|
1702
|
-
result = self._db_node.
|
1706
|
+
result = self._db_node.execute(
|
1703
1707
|
query=users_query,
|
1704
1708
|
parameters=[role_id, tenant_id, limit, offset],
|
1705
1709
|
fetch_mode="all",
|
@@ -1713,7 +1717,7 @@ class RoleManagementNode(Node):
|
|
1713
1717
|
WHERE role_id = $1 AND tenant_id = $2
|
1714
1718
|
"""
|
1715
1719
|
|
1716
|
-
count_result = self._db_node.
|
1720
|
+
count_result = self._db_node.execute(
|
1717
1721
|
query=count_query, parameters=[role_id, tenant_id], fetch_mode="one"
|
1718
1722
|
)
|
1719
1723
|
total_count = count_result.get("data", [{}])[0].get("total", 0)
|
@@ -1921,7 +1925,7 @@ class RoleManagementNode(Node):
|
|
1921
1925
|
WHERE role_id = $3 AND tenant_id = $4
|
1922
1926
|
"""
|
1923
1927
|
|
1924
|
-
self._db_node.
|
1928
|
+
self._db_node.execute(
|
1925
1929
|
query=update_query,
|
1926
1930
|
parameters=[
|
1927
1931
|
orphaned_child_id,
|
@@ -1951,7 +1955,7 @@ class RoleManagementNode(Node):
|
|
1951
1955
|
))
|
1952
1956
|
"""
|
1953
1957
|
|
1954
|
-
self._db_node.
|
1958
|
+
self._db_node.execute(
|
1955
1959
|
query=add_child_query,
|
1956
1960
|
parameters=[child_role_id, datetime.now(UTC), parent_role_id, tenant_id],
|
1957
1961
|
)
|
kailash/nodes/admin/schema.sql
CHANGED
@@ -346,19 +346,24 @@ BEGIN
|
|
346
346
|
END;
|
347
347
|
$$ language 'plpgsql';
|
348
348
|
|
349
|
-
-- Apply auto-update triggers
|
349
|
+
-- Apply auto-update triggers with conflict resolution
|
350
|
+
DROP TRIGGER IF EXISTS update_users_updated_at ON users;
|
350
351
|
CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users
|
351
352
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
352
353
|
|
354
|
+
DROP TRIGGER IF EXISTS update_roles_updated_at ON roles;
|
353
355
|
CREATE TRIGGER update_roles_updated_at BEFORE UPDATE ON roles
|
354
356
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
355
357
|
|
358
|
+
DROP TRIGGER IF EXISTS update_permissions_updated_at ON permissions;
|
356
359
|
CREATE TRIGGER update_permissions_updated_at BEFORE UPDATE ON permissions
|
357
360
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
358
361
|
|
362
|
+
DROP TRIGGER IF EXISTS update_user_attributes_updated_at ON user_attributes;
|
359
363
|
CREATE TRIGGER update_user_attributes_updated_at BEFORE UPDATE ON user_attributes
|
360
364
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
361
365
|
|
366
|
+
DROP TRIGGER IF EXISTS update_resource_attributes_updated_at ON resource_attributes;
|
362
367
|
CREATE TRIGGER update_resource_attributes_updated_at BEFORE UPDATE ON resource_attributes
|
363
368
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
364
369
|
|
@@ -57,7 +57,7 @@ class AdminSchemaManager:
|
|
57
57
|
schema_sql = f.read()
|
58
58
|
|
59
59
|
# Execute schema creation
|
60
|
-
self.db_node.
|
60
|
+
self.db_node.execute(query=schema_sql)
|
61
61
|
|
62
62
|
# Verify schema creation
|
63
63
|
tables = self._get_existing_tables()
|
@@ -113,7 +113,7 @@ class AdminSchemaManager:
|
|
113
113
|
|
114
114
|
# Check schema version
|
115
115
|
try:
|
116
|
-
version_result = self.db_node.
|
116
|
+
version_result = self.db_node.execute(
|
117
117
|
query="SELECT version FROM admin_schema_version ORDER BY created_at DESC LIMIT 1",
|
118
118
|
result_format="dict",
|
119
119
|
)
|
@@ -225,14 +225,14 @@ class AdminSchemaManager:
|
|
225
225
|
|
226
226
|
for table in tables_to_drop:
|
227
227
|
try:
|
228
|
-
self.db_node.
|
228
|
+
self.db_node.execute(query=f"DROP TABLE IF EXISTS {table} CASCADE")
|
229
229
|
except Exception as e:
|
230
230
|
self.logger.warning(f"Could not drop table {table}: {e}")
|
231
231
|
|
232
232
|
def _get_existing_tables(self) -> List[str]:
|
233
233
|
"""Get list of existing tables in the database."""
|
234
234
|
try:
|
235
|
-
result = self.db_node.
|
235
|
+
result = self.db_node.execute(
|
236
236
|
query="""
|
237
237
|
SELECT table_name
|
238
238
|
FROM information_schema.tables
|
@@ -252,7 +252,7 @@ class AdminSchemaManager:
|
|
252
252
|
def _get_existing_indexes(self) -> List[str]:
|
253
253
|
"""Get list of existing indexes."""
|
254
254
|
try:
|
255
|
-
result = self.db_node.
|
255
|
+
result = self.db_node.execute(
|
256
256
|
query="""
|
257
257
|
SELECT indexname
|
258
258
|
FROM pg_indexes
|
@@ -280,11 +280,11 @@ class AdminSchemaManager:
|
|
280
280
|
)
|
281
281
|
"""
|
282
282
|
|
283
|
-
self.db_node.
|
283
|
+
self.db_node.execute(query=version_table_sql)
|
284
284
|
|
285
285
|
def _record_schema_version(self):
|
286
286
|
"""Record the current schema version."""
|
287
|
-
self.db_node.
|
287
|
+
self.db_node.execute(
|
288
288
|
query="""
|
289
289
|
INSERT INTO admin_schema_version (version, migration_notes)
|
290
290
|
VALUES ($1, $2)
|
@@ -298,7 +298,7 @@ class AdminSchemaManager:
|
|
298
298
|
def _get_current_schema_version(self) -> Optional[str]:
|
299
299
|
"""Get the current schema version."""
|
300
300
|
try:
|
301
|
-
result = self.db_node.
|
301
|
+
result = self.db_node.execute(
|
302
302
|
query="SELECT version FROM admin_schema_version ORDER BY created_at DESC LIMIT 1",
|
303
303
|
result_format="dict",
|
304
304
|
)
|
@@ -350,7 +350,7 @@ class AdminSchemaManager:
|
|
350
350
|
def _get_table_columns(self, table_name: str) -> List[str]:
|
351
351
|
"""Get column names for a table."""
|
352
352
|
try:
|
353
|
-
result = self.db_node.
|
353
|
+
result = self.db_node.execute(
|
354
354
|
query="""
|
355
355
|
SELECT column_name
|
356
356
|
FROM information_schema.columns
|
@@ -370,7 +370,7 @@ class AdminSchemaManager:
|
|
370
370
|
def _get_table_info(self) -> Dict[str, Any]:
|
371
371
|
"""Get detailed table information."""
|
372
372
|
try:
|
373
|
-
result = self.db_node.
|
373
|
+
result = self.db_node.execute(
|
374
374
|
query="""
|
375
375
|
SELECT
|
376
376
|
t.table_name,
|
@@ -398,7 +398,7 @@ class AdminSchemaManager:
|
|
398
398
|
|
399
399
|
for table in tables:
|
400
400
|
try:
|
401
|
-
result = self.db_node.
|
401
|
+
result = self.db_node.execute(
|
402
402
|
query=f"SELECT COUNT(*) as count FROM {table}",
|
403
403
|
result_format="dict",
|
404
404
|
)
|
@@ -411,11 +411,11 @@ class AdminSchemaManager:
|
|
411
411
|
def _get_database_info(self) -> Dict[str, Any]:
|
412
412
|
"""Get general database information."""
|
413
413
|
try:
|
414
|
-
version_result = self.db_node.
|
414
|
+
version_result = self.db_node.execute(
|
415
415
|
query="SELECT version()", result_format="dict"
|
416
416
|
)
|
417
417
|
|
418
|
-
size_result = self.db_node.
|
418
|
+
size_result = self.db_node.execute(
|
419
419
|
query="SELECT pg_size_pretty(pg_database_size(current_database())) as size",
|
420
420
|
result_format="dict",
|
421
421
|
)
|
@@ -24,11 +24,7 @@ from enum import Enum
|
|
24
24
|
from typing import Any, Dict, List, Optional, Tuple
|
25
25
|
|
26
26
|
from kailash.access_control import UserContext
|
27
|
-
from kailash.nodes.admin.audit_log import
|
28
|
-
AuditEventType,
|
29
|
-
AuditSeverity,
|
30
|
-
EnterpriseAuditLogNode,
|
31
|
-
)
|
27
|
+
from kailash.nodes.admin.audit_log import AuditEventType, AuditSeverity, EnterpriseAuditLogNode
|
32
28
|
from kailash.nodes.base import Node, NodeParameter, register_node
|
33
29
|
from kailash.nodes.data import AsyncSQLDatabaseNode
|
34
30
|
from kailash.sdk_exceptions import NodeExecutionError, NodeValidationError
|
@@ -214,7 +210,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
214
210
|
... "detection_method": "geolocation_analysis"
|
215
211
|
... }
|
216
212
|
... )
|
217
|
-
>>> result = node.
|
213
|
+
>>> result = node.execute()
|
218
214
|
>>> event_id = result["security_event"]["event_id"]
|
219
215
|
|
220
216
|
>>> # Analyze threats in time window
|
@@ -226,7 +222,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
226
222
|
... "risk_threshold": 7.0
|
227
223
|
... }
|
228
224
|
... )
|
229
|
-
>>> result = node.
|
225
|
+
>>> result = node.execute()
|
230
226
|
>>> threats = result["threat_analysis"]["high_risk_events"]
|
231
227
|
|
232
228
|
>>> # Monitor user behavior for anomalies
|
@@ -238,7 +234,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
238
234
|
... "anomaly_threshold": 0.8
|
239
235
|
... }
|
240
236
|
... )
|
241
|
-
>>> result = node.
|
237
|
+
>>> result = node.execute()
|
242
238
|
>>> anomalies = result["behavior_analysis"]["anomalies"]
|
243
239
|
"""
|
244
240
|
|
@@ -487,7 +483,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
487
483
|
}
|
488
484
|
)
|
489
485
|
|
490
|
-
db_result = self._db_node.
|
486
|
+
db_result = self._db_node.execute()
|
491
487
|
|
492
488
|
# Log to audit trail
|
493
489
|
audit_event_data = {
|
@@ -504,7 +500,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
504
500
|
},
|
505
501
|
}
|
506
502
|
|
507
|
-
self._audit_node.
|
503
|
+
self._audit_node.execute(
|
508
504
|
operation="log_event", event_data=audit_event_data, tenant_id=tenant_id
|
509
505
|
)
|
510
506
|
|
@@ -552,7 +548,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
552
548
|
}
|
553
549
|
)
|
554
550
|
|
555
|
-
result = self._db_node.
|
551
|
+
result = self._db_node.execute()
|
556
552
|
events = result.get("result", {}).get("data", [])
|
557
553
|
|
558
554
|
# Analyze threats
|
@@ -600,7 +596,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
600
596
|
}
|
601
597
|
)
|
602
598
|
|
603
|
-
result = self._db_node.
|
599
|
+
result = self._db_node.execute()
|
604
600
|
events = result.get("result", {}).get("data", [])
|
605
601
|
|
606
602
|
# Analyze behavior patterns
|
@@ -829,7 +825,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
829
825
|
}
|
830
826
|
)
|
831
827
|
|
832
|
-
self._db_node.
|
828
|
+
self._db_node.execute()
|
833
829
|
|
834
830
|
return incident_id
|
835
831
|
|
@@ -869,7 +865,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
869
865
|
{"query": query, "params": params, "fetch_mode": "all"}
|
870
866
|
)
|
871
867
|
|
872
|
-
result = self._db_node.
|
868
|
+
result = self._db_node.execute()
|
873
869
|
events = result.get("result", {}).get("data", [])
|
874
870
|
|
875
871
|
# Perform anomaly detection
|
@@ -917,7 +913,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
917
913
|
}
|
918
914
|
)
|
919
915
|
|
920
|
-
result = self._db_node.
|
916
|
+
result = self._db_node.execute()
|
921
917
|
high_risk_events = result.get("result", {}).get("data", [])
|
922
918
|
|
923
919
|
# Generate alerts
|
@@ -995,7 +991,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
995
991
|
{"query": query, "params": params, "fetch_mode": "all"}
|
996
992
|
)
|
997
993
|
|
998
|
-
result = self._db_node.
|
994
|
+
result = self._db_node.execute()
|
999
995
|
incidents = result.get("result", {}).get("data", [])
|
1000
996
|
|
1001
997
|
return {
|
@@ -1071,7 +1067,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
1071
1067
|
}
|
1072
1068
|
)
|
1073
1069
|
|
1074
|
-
self._db_node.
|
1070
|
+
self._db_node.execute()
|
1075
1071
|
|
1076
1072
|
return {
|
1077
1073
|
"result": {
|
@@ -1127,7 +1123,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
1127
1123
|
|
1128
1124
|
self._db_node.config.update({"query": query, "params": params})
|
1129
1125
|
|
1130
|
-
self._db_node.
|
1126
|
+
self._db_node.execute()
|
1131
1127
|
|
1132
1128
|
return {
|
1133
1129
|
"result": {
|
@@ -1217,7 +1213,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
1217
1213
|
}
|
1218
1214
|
)
|
1219
1215
|
|
1220
|
-
result = self._db_node.
|
1216
|
+
result = self._db_node.execute()
|
1221
1217
|
events = result.get("result", {}).get("data", [])
|
1222
1218
|
|
1223
1219
|
# Calculate risk metrics
|
@@ -1347,7 +1343,7 @@ class EnterpriseSecurityEventNode(Node):
|
|
1347
1343
|
{"query": query, "params": params, "fetch_mode": "all"}
|
1348
1344
|
)
|
1349
1345
|
|
1350
|
-
result = self._db_node.
|
1346
|
+
result = self._db_node.execute()
|
1351
1347
|
events = result.get("result", {}).get("data", [])
|
1352
1348
|
|
1353
1349
|
# Perform forensic analysis
|
@@ -59,7 +59,7 @@ class TenantIsolationManager:
|
|
59
59
|
users_query = """
|
60
60
|
SELECT user_id FROM users WHERE tenant_id = $1 AND status = 'active'
|
61
61
|
"""
|
62
|
-
users_result = self.db_node.
|
62
|
+
users_result = self.db_node.execute(
|
63
63
|
query=users_query, parameters=[tenant_id], result_format="dict"
|
64
64
|
)
|
65
65
|
user_ids = {row["user_id"] for row in users_result.get("data", [])}
|
@@ -68,7 +68,7 @@ class TenantIsolationManager:
|
|
68
68
|
roles_query = """
|
69
69
|
SELECT role_id FROM roles WHERE tenant_id = $1 AND is_active = true
|
70
70
|
"""
|
71
|
-
roles_result = self.db_node.
|
71
|
+
roles_result = self.db_node.execute(
|
72
72
|
query=roles_query, parameters=[tenant_id], result_format="dict"
|
73
73
|
)
|
74
74
|
role_ids = {row["role_id"] for row in roles_result.get("data", [])}
|
@@ -85,7 +85,7 @@ class TenantIsolationManager:
|
|
85
85
|
FROM roles
|
86
86
|
WHERE tenant_id = $1 AND is_active = true
|
87
87
|
"""
|
88
|
-
permissions_result = self.db_node.
|
88
|
+
permissions_result = self.db_node.execute(
|
89
89
|
query=permissions_query, parameters=[tenant_id], result_format="dict"
|
90
90
|
)
|
91
91
|
permissions = {row["permission"] for row in permissions_result.get("data", [])}
|
@@ -96,7 +96,7 @@ class TransactionHelper:
|
|
96
96
|
|
97
97
|
while time.time() - start_time < timeout_seconds:
|
98
98
|
try:
|
99
|
-
result = self.db_node.
|
99
|
+
result = self.db_node.execute(
|
100
100
|
query=verification_query, result_format="dict"
|
101
101
|
)
|
102
102
|
data = result.get("data", [])
|
@@ -136,7 +136,7 @@ class TransactionHelper:
|
|
136
136
|
from .user_management import UserManagementNode
|
137
137
|
|
138
138
|
user_mgmt = UserManagementNode(database_url=self.db_node.connection_string)
|
139
|
-
return user_mgmt.
|
139
|
+
return user_mgmt.execute(
|
140
140
|
operation="create_user", user_data=user_data, tenant_id=tenant_id
|
141
141
|
)
|
142
142
|
|
@@ -179,7 +179,7 @@ class TransactionHelper:
|
|
179
179
|
from .role_management import RoleManagementNode
|
180
180
|
|
181
181
|
role_mgmt = RoleManagementNode(database_url=self.db_node.connection_string)
|
182
|
-
return role_mgmt.
|
182
|
+
return role_mgmt.execute(
|
183
183
|
operation="assign_user",
|
184
184
|
user_id=user_id,
|
185
185
|
role_id=role_id,
|