holmesgpt 0.11.5__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.
Potentially problematic release.
This version of holmesgpt might be problematic. Click here for more details.
- holmes/.git_archival.json +7 -0
- holmes/__init__.py +76 -0
- holmes/__init__.py.bak +76 -0
- holmes/clients/robusta_client.py +24 -0
- holmes/common/env_vars.py +47 -0
- holmes/config.py +526 -0
- holmes/core/__init__.py +0 -0
- holmes/core/conversations.py +578 -0
- holmes/core/investigation.py +152 -0
- holmes/core/investigation_structured_output.py +264 -0
- holmes/core/issue.py +54 -0
- holmes/core/llm.py +250 -0
- holmes/core/models.py +157 -0
- holmes/core/openai_formatting.py +51 -0
- holmes/core/performance_timing.py +72 -0
- holmes/core/prompt.py +42 -0
- holmes/core/resource_instruction.py +17 -0
- holmes/core/runbooks.py +26 -0
- holmes/core/safeguards.py +120 -0
- holmes/core/supabase_dal.py +540 -0
- holmes/core/tool_calling_llm.py +798 -0
- holmes/core/tools.py +566 -0
- holmes/core/tools_utils/__init__.py +0 -0
- holmes/core/tools_utils/tool_executor.py +65 -0
- holmes/core/tools_utils/toolset_utils.py +52 -0
- holmes/core/toolset_manager.py +418 -0
- holmes/interactive.py +229 -0
- holmes/main.py +1041 -0
- holmes/plugins/__init__.py +0 -0
- holmes/plugins/destinations/__init__.py +6 -0
- holmes/plugins/destinations/slack/__init__.py +2 -0
- holmes/plugins/destinations/slack/plugin.py +163 -0
- holmes/plugins/interfaces.py +32 -0
- holmes/plugins/prompts/__init__.py +48 -0
- holmes/plugins/prompts/_current_date_time.jinja2 +1 -0
- holmes/plugins/prompts/_default_log_prompt.jinja2 +11 -0
- holmes/plugins/prompts/_fetch_logs.jinja2 +36 -0
- holmes/plugins/prompts/_general_instructions.jinja2 +86 -0
- holmes/plugins/prompts/_global_instructions.jinja2 +12 -0
- holmes/plugins/prompts/_runbook_instructions.jinja2 +13 -0
- holmes/plugins/prompts/_toolsets_instructions.jinja2 +56 -0
- holmes/plugins/prompts/generic_ask.jinja2 +36 -0
- holmes/plugins/prompts/generic_ask_conversation.jinja2 +32 -0
- holmes/plugins/prompts/generic_ask_for_issue_conversation.jinja2 +50 -0
- holmes/plugins/prompts/generic_investigation.jinja2 +42 -0
- holmes/plugins/prompts/generic_post_processing.jinja2 +13 -0
- holmes/plugins/prompts/generic_ticket.jinja2 +12 -0
- holmes/plugins/prompts/investigation_output_format.jinja2 +32 -0
- holmes/plugins/prompts/kubernetes_workload_ask.jinja2 +84 -0
- holmes/plugins/prompts/kubernetes_workload_chat.jinja2 +39 -0
- holmes/plugins/runbooks/README.md +22 -0
- holmes/plugins/runbooks/__init__.py +100 -0
- holmes/plugins/runbooks/catalog.json +14 -0
- holmes/plugins/runbooks/jira.yaml +12 -0
- holmes/plugins/runbooks/kube-prometheus-stack.yaml +10 -0
- holmes/plugins/runbooks/networking/dns_troubleshooting_instructions.md +66 -0
- holmes/plugins/runbooks/upgrade/upgrade_troubleshooting_instructions.md +44 -0
- holmes/plugins/sources/github/__init__.py +77 -0
- holmes/plugins/sources/jira/__init__.py +123 -0
- holmes/plugins/sources/opsgenie/__init__.py +93 -0
- holmes/plugins/sources/pagerduty/__init__.py +147 -0
- holmes/plugins/sources/prometheus/__init__.py +0 -0
- holmes/plugins/sources/prometheus/models.py +104 -0
- holmes/plugins/sources/prometheus/plugin.py +154 -0
- holmes/plugins/toolsets/__init__.py +171 -0
- holmes/plugins/toolsets/aks-node-health.yaml +65 -0
- holmes/plugins/toolsets/aks.yaml +86 -0
- holmes/plugins/toolsets/argocd.yaml +70 -0
- holmes/plugins/toolsets/atlas_mongodb/instructions.jinja2 +8 -0
- holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py +307 -0
- holmes/plugins/toolsets/aws.yaml +76 -0
- holmes/plugins/toolsets/azure_sql/__init__.py +0 -0
- holmes/plugins/toolsets/azure_sql/apis/alert_monitoring_api.py +600 -0
- holmes/plugins/toolsets/azure_sql/apis/azure_sql_api.py +309 -0
- holmes/plugins/toolsets/azure_sql/apis/connection_failure_api.py +445 -0
- holmes/plugins/toolsets/azure_sql/apis/connection_monitoring_api.py +251 -0
- holmes/plugins/toolsets/azure_sql/apis/storage_analysis_api.py +317 -0
- holmes/plugins/toolsets/azure_sql/azure_base_toolset.py +55 -0
- holmes/plugins/toolsets/azure_sql/azure_sql_instructions.jinja2 +137 -0
- holmes/plugins/toolsets/azure_sql/azure_sql_toolset.py +183 -0
- holmes/plugins/toolsets/azure_sql/install.md +66 -0
- holmes/plugins/toolsets/azure_sql/tools/__init__.py +1 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_connection_failures.py +324 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_connections.py +243 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_health_status.py +205 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_performance.py +249 -0
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_storage.py +373 -0
- holmes/plugins/toolsets/azure_sql/tools/get_active_alerts.py +237 -0
- holmes/plugins/toolsets/azure_sql/tools/get_slow_queries.py +172 -0
- holmes/plugins/toolsets/azure_sql/tools/get_top_cpu_queries.py +170 -0
- holmes/plugins/toolsets/azure_sql/tools/get_top_data_io_queries.py +188 -0
- holmes/plugins/toolsets/azure_sql/tools/get_top_log_io_queries.py +180 -0
- holmes/plugins/toolsets/azure_sql/utils.py +83 -0
- holmes/plugins/toolsets/bash/__init__.py +0 -0
- holmes/plugins/toolsets/bash/bash_instructions.jinja2 +14 -0
- holmes/plugins/toolsets/bash/bash_toolset.py +208 -0
- holmes/plugins/toolsets/bash/common/bash.py +52 -0
- holmes/plugins/toolsets/bash/common/config.py +14 -0
- holmes/plugins/toolsets/bash/common/stringify.py +25 -0
- holmes/plugins/toolsets/bash/common/validators.py +24 -0
- holmes/plugins/toolsets/bash/grep/__init__.py +52 -0
- holmes/plugins/toolsets/bash/kubectl/__init__.py +100 -0
- holmes/plugins/toolsets/bash/kubectl/constants.py +96 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_describe.py +66 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_events.py +88 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_get.py +108 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_logs.py +20 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_run.py +46 -0
- holmes/plugins/toolsets/bash/kubectl/kubectl_top.py +81 -0
- holmes/plugins/toolsets/bash/parse_command.py +103 -0
- holmes/plugins/toolsets/confluence.yaml +19 -0
- holmes/plugins/toolsets/consts.py +5 -0
- holmes/plugins/toolsets/coralogix/api.py +158 -0
- holmes/plugins/toolsets/coralogix/toolset_coralogix_logs.py +103 -0
- holmes/plugins/toolsets/coralogix/utils.py +181 -0
- holmes/plugins/toolsets/datadog.py +153 -0
- holmes/plugins/toolsets/docker.yaml +46 -0
- holmes/plugins/toolsets/git.py +756 -0
- holmes/plugins/toolsets/grafana/__init__.py +0 -0
- holmes/plugins/toolsets/grafana/base_grafana_toolset.py +54 -0
- holmes/plugins/toolsets/grafana/common.py +68 -0
- holmes/plugins/toolsets/grafana/grafana_api.py +31 -0
- holmes/plugins/toolsets/grafana/loki_api.py +89 -0
- holmes/plugins/toolsets/grafana/tempo_api.py +124 -0
- holmes/plugins/toolsets/grafana/toolset_grafana.py +102 -0
- holmes/plugins/toolsets/grafana/toolset_grafana_loki.py +102 -0
- holmes/plugins/toolsets/grafana/toolset_grafana_tempo.jinja2 +10 -0
- holmes/plugins/toolsets/grafana/toolset_grafana_tempo.py +299 -0
- holmes/plugins/toolsets/grafana/trace_parser.py +195 -0
- holmes/plugins/toolsets/helm.yaml +42 -0
- holmes/plugins/toolsets/internet/internet.py +275 -0
- holmes/plugins/toolsets/internet/notion.py +137 -0
- holmes/plugins/toolsets/kafka.py +638 -0
- holmes/plugins/toolsets/kubernetes.yaml +255 -0
- holmes/plugins/toolsets/kubernetes_logs.py +426 -0
- holmes/plugins/toolsets/kubernetes_logs.yaml +42 -0
- holmes/plugins/toolsets/logging_utils/__init__.py +0 -0
- holmes/plugins/toolsets/logging_utils/logging_api.py +217 -0
- holmes/plugins/toolsets/logging_utils/types.py +0 -0
- holmes/plugins/toolsets/mcp/toolset_mcp.py +135 -0
- holmes/plugins/toolsets/newrelic.py +222 -0
- holmes/plugins/toolsets/opensearch/__init__.py +0 -0
- holmes/plugins/toolsets/opensearch/opensearch.py +245 -0
- holmes/plugins/toolsets/opensearch/opensearch_logs.py +151 -0
- holmes/plugins/toolsets/opensearch/opensearch_traces.py +211 -0
- holmes/plugins/toolsets/opensearch/opensearch_traces_instructions.jinja2 +12 -0
- holmes/plugins/toolsets/opensearch/opensearch_utils.py +166 -0
- holmes/plugins/toolsets/prometheus/prometheus.py +818 -0
- holmes/plugins/toolsets/prometheus/prometheus_instructions.jinja2 +38 -0
- holmes/plugins/toolsets/rabbitmq/api.py +398 -0
- holmes/plugins/toolsets/rabbitmq/rabbitmq_instructions.jinja2 +37 -0
- holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py +222 -0
- holmes/plugins/toolsets/robusta/__init__.py +0 -0
- holmes/plugins/toolsets/robusta/robusta.py +235 -0
- holmes/plugins/toolsets/robusta/robusta_instructions.jinja2 +24 -0
- holmes/plugins/toolsets/runbook/__init__.py +0 -0
- holmes/plugins/toolsets/runbook/runbook_fetcher.py +78 -0
- holmes/plugins/toolsets/service_discovery.py +92 -0
- holmes/plugins/toolsets/servicenow/install.md +37 -0
- holmes/plugins/toolsets/servicenow/instructions.jinja2 +3 -0
- holmes/plugins/toolsets/servicenow/servicenow.py +198 -0
- holmes/plugins/toolsets/slab.yaml +20 -0
- holmes/plugins/toolsets/utils.py +137 -0
- holmes/plugins/utils.py +14 -0
- holmes/utils/__init__.py +0 -0
- holmes/utils/cache.py +84 -0
- holmes/utils/cert_utils.py +40 -0
- holmes/utils/default_toolset_installation_guide.jinja2 +44 -0
- holmes/utils/definitions.py +13 -0
- holmes/utils/env.py +53 -0
- holmes/utils/file_utils.py +56 -0
- holmes/utils/global_instructions.py +20 -0
- holmes/utils/holmes_status.py +22 -0
- holmes/utils/holmes_sync_toolsets.py +80 -0
- holmes/utils/markdown_utils.py +55 -0
- holmes/utils/pydantic_utils.py +54 -0
- holmes/utils/robusta.py +10 -0
- holmes/utils/tags.py +97 -0
- holmesgpt-0.11.5.dist-info/LICENSE.txt +21 -0
- holmesgpt-0.11.5.dist-info/METADATA +400 -0
- holmesgpt-0.11.5.dist-info/RECORD +183 -0
- holmesgpt-0.11.5.dist-info/WHEEL +4 -0
- holmesgpt-0.11.5.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import requests # type: ignore
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Any, Dict, Tuple, List
|
|
4
|
+
from holmes.core.tools import (
|
|
5
|
+
CallablePrerequisite,
|
|
6
|
+
Tool,
|
|
7
|
+
ToolParameter,
|
|
8
|
+
Toolset,
|
|
9
|
+
ToolsetTag,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from pydantic import BaseModel, PrivateAttr
|
|
13
|
+
from holmes.core.tools import StructuredToolResult, ToolResultStatus
|
|
14
|
+
from requests.auth import HTTPDigestAuth # type: ignore
|
|
15
|
+
import gzip
|
|
16
|
+
import io
|
|
17
|
+
from datetime import datetime, timedelta, timezone
|
|
18
|
+
import os
|
|
19
|
+
from collections import Counter
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class MongoDBConfig(BaseModel):
|
|
23
|
+
public_key: str
|
|
24
|
+
private_key: str
|
|
25
|
+
project_id: str
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/
|
|
29
|
+
class MongoDBAtlasToolset(Toolset):
|
|
30
|
+
name: str = "MongoDBAtlas"
|
|
31
|
+
description: str = "The MongoDB Atlas API allows access to Mongodb projects and processes. You can find logs, alerts, events, slow queries and various metrics to understand the state of Mongodb projects."
|
|
32
|
+
docs_url: str = (
|
|
33
|
+
"https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/"
|
|
34
|
+
)
|
|
35
|
+
icon_url: str = "https://webimages.mongodb.com/_com_assets/cms/kuyjf3vea2hg34taa-horizontal_default_slate_blue.svg?auto=format%252Ccompress"
|
|
36
|
+
tags: List[ToolsetTag] = [ToolsetTag.CORE]
|
|
37
|
+
_session: requests.Session = PrivateAttr(default=requests.Session())
|
|
38
|
+
|
|
39
|
+
def __init__(self):
|
|
40
|
+
super().__init__(
|
|
41
|
+
prerequisites=[CallablePrerequisite(callable=self.prerequisites_callable)],
|
|
42
|
+
experimental=True,
|
|
43
|
+
tools=[
|
|
44
|
+
ReturnProjectAlerts(toolset=self),
|
|
45
|
+
ReturnProjectProcesses(toolset=self),
|
|
46
|
+
ReturnProjectSlowQueries(toolset=self),
|
|
47
|
+
ReturnEventsFromProject(toolset=self),
|
|
48
|
+
ReturnLogsForProcessInProject(toolset=self),
|
|
49
|
+
ReturnEventTypeFromProject(toolset=self),
|
|
50
|
+
],
|
|
51
|
+
)
|
|
52
|
+
instructions_filepath = os.path.abspath(
|
|
53
|
+
os.path.join(os.path.dirname(__file__), "instructions.jinja2")
|
|
54
|
+
)
|
|
55
|
+
self._load_llm_instructions(jinja_template=f"file://{instructions_filepath}")
|
|
56
|
+
|
|
57
|
+
def prerequisites_callable(self, config: dict[str, Any]) -> Tuple[bool, str]:
|
|
58
|
+
if not config:
|
|
59
|
+
return False, "Missing config credentials."
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
self.config: Dict = MongoDBConfig(**config).model_dump()
|
|
63
|
+
self._session.headers.update(
|
|
64
|
+
{"Accept": "application/vnd.atlas.2025-03-12+json"}
|
|
65
|
+
)
|
|
66
|
+
self._session.auth = HTTPDigestAuth(
|
|
67
|
+
self.config.get("public_key"),
|
|
68
|
+
self.config.get("private_key"),
|
|
69
|
+
)
|
|
70
|
+
return True, ""
|
|
71
|
+
except Exception:
|
|
72
|
+
logging.exception(
|
|
73
|
+
"Invalid Atlas config. Failed to set up MongoDBAtlas toolset"
|
|
74
|
+
)
|
|
75
|
+
return False, "Invalid Atlas config"
|
|
76
|
+
|
|
77
|
+
def get_example_config(self) -> Dict[str, Any]:
|
|
78
|
+
return {}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class MongoDBAtlasBaseTool(Tool):
|
|
82
|
+
toolset: MongoDBAtlasToolset
|
|
83
|
+
|
|
84
|
+
def return_result(
|
|
85
|
+
self, response: requests.Response, params: Any, field: str = "results"
|
|
86
|
+
) -> StructuredToolResult:
|
|
87
|
+
response.raise_for_status()
|
|
88
|
+
if response.ok:
|
|
89
|
+
res = response.json()
|
|
90
|
+
return StructuredToolResult(
|
|
91
|
+
status=ToolResultStatus.SUCCESS
|
|
92
|
+
if res.get(field, [])
|
|
93
|
+
else ToolResultStatus.NO_DATA,
|
|
94
|
+
data=res,
|
|
95
|
+
params=params,
|
|
96
|
+
)
|
|
97
|
+
else:
|
|
98
|
+
return StructuredToolResult(
|
|
99
|
+
status=ToolResultStatus.ERROR,
|
|
100
|
+
error=f"Failed {self.name}.\n{response.text}",
|
|
101
|
+
return_code=response.status_code,
|
|
102
|
+
params=params,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def get_parameterized_one_liner(self, params) -> str:
|
|
106
|
+
return f"MongoDB {self.name} project {self.toolset.config.get('project_id')} {params}"
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
# https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/#tag/Alerts/operation/listAlertsByAlertConfigurationId
|
|
110
|
+
class ReturnProjectAlerts(MongoDBAtlasBaseTool):
|
|
111
|
+
name: str = "atlas_return_project_alerts"
|
|
112
|
+
description: str = "Returns all project alerts. These alerts apply to all components in one project. You receive an alert when a monitored component meets or exceeds a value you set."
|
|
113
|
+
|
|
114
|
+
def _invoke(self, params: Any) -> StructuredToolResult:
|
|
115
|
+
try:
|
|
116
|
+
url = "https://cloud.mongodb.com/api/atlas/v2/groups/{project_id}/alerts".format(
|
|
117
|
+
project_id=self.toolset.config.get("project_id")
|
|
118
|
+
)
|
|
119
|
+
response = self.toolset._session.get(url=url)
|
|
120
|
+
return self.return_result(response, params)
|
|
121
|
+
except Exception as e:
|
|
122
|
+
logging.exception(self.get_parameterized_one_liner(params))
|
|
123
|
+
return StructuredToolResult(
|
|
124
|
+
status=ToolResultStatus.ERROR,
|
|
125
|
+
data=f"Exception {self.name}: {str(e)}",
|
|
126
|
+
params=params,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/#tag/Monitoring-and-Logs/operation/listAtlasProcesses
|
|
131
|
+
class ReturnProjectProcesses(MongoDBAtlasBaseTool):
|
|
132
|
+
name: str = "atlas_return_project_processes"
|
|
133
|
+
description: str = "Returns details of all processes for the specified project. Useful for getting logs and data for specific project"
|
|
134
|
+
|
|
135
|
+
def _invoke(self, params: Any) -> StructuredToolResult:
|
|
136
|
+
try:
|
|
137
|
+
url = "https://cloud.mongodb.com/api/atlas/v2/groups/{project_id}/processes".format(
|
|
138
|
+
project_id=self.toolset.config.get("project_id")
|
|
139
|
+
)
|
|
140
|
+
response = self.toolset._session.get(url)
|
|
141
|
+
return self.return_result(response, params)
|
|
142
|
+
except Exception as e:
|
|
143
|
+
logging.exception(self.get_parameterized_one_liner(params))
|
|
144
|
+
return StructuredToolResult(
|
|
145
|
+
status=ToolResultStatus.ERROR,
|
|
146
|
+
error=f"Exception {self.name}: {str(e)}",
|
|
147
|
+
params=params,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/#tag/Performance-Advisor/operation/listSlowQueries
|
|
152
|
+
class ReturnProjectSlowQueries(MongoDBAtlasBaseTool):
|
|
153
|
+
name: str = "atlas_return_project_processes_slow_queries"
|
|
154
|
+
description: str = "Returns log lines for slow queries that the Performance Advisor and Query Profiler identified for a specific process in a specific project. requires fetching the project processes first. returns queries from the last 24 hours."
|
|
155
|
+
url: str = "https://cloud.mongodb.com/api/atlas/v2/groups/{project_id}/processes/{process_id}/performanceAdvisor/slowQueryLogs?includeMetrics=true"
|
|
156
|
+
parameters: Dict[str, ToolParameter] = {
|
|
157
|
+
"process_id": ToolParameter(
|
|
158
|
+
description="Combination of host and port that serves the MongoDB process. call tool atlas_return_project_processes tool to get host+port of project procecess.",
|
|
159
|
+
type="string",
|
|
160
|
+
required=True,
|
|
161
|
+
),
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
def _invoke(self, params: Any) -> StructuredToolResult:
|
|
165
|
+
try:
|
|
166
|
+
url = self.url.format(
|
|
167
|
+
project_id=self.toolset.config.get("project_id"),
|
|
168
|
+
process_id=params.pop("process_id", ""),
|
|
169
|
+
)
|
|
170
|
+
response = self.toolset._session.get(url)
|
|
171
|
+
return self.return_result(response, params, "slowQueries")
|
|
172
|
+
except Exception as e:
|
|
173
|
+
logging.exception(self.get_parameterized_one_liner(params))
|
|
174
|
+
return StructuredToolResult(
|
|
175
|
+
status=ToolResultStatus.ERROR,
|
|
176
|
+
error=f"Exception {self.name}: {str(e)}",
|
|
177
|
+
params=params,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
# https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/#tag/Events/operation/listProjectEvents
|
|
182
|
+
class ReturnEventsFromProject(MongoDBAtlasBaseTool):
|
|
183
|
+
name: str = "atlas_return_events_from_project"
|
|
184
|
+
description: str = "Returns all events occurrences for the specified project. Events identify significant database, security activities or status changes. can only query the last 4 hours."
|
|
185
|
+
url: str = "https://cloud.mongodb.com/api/atlas/v2/groups/{projectId}/events"
|
|
186
|
+
|
|
187
|
+
def _invoke(self, params: Any) -> StructuredToolResult:
|
|
188
|
+
params.update({"itemsPerPage": 500})
|
|
189
|
+
try:
|
|
190
|
+
now_utc = datetime.now(timezone.utc)
|
|
191
|
+
four_hours_ago = now_utc - timedelta(hours=4)
|
|
192
|
+
iso_timestamp = four_hours_ago.isoformat()
|
|
193
|
+
url = self.url.format(projectId=self.toolset.config.get("project_id"))
|
|
194
|
+
response = self.toolset._session.get(
|
|
195
|
+
url=url,
|
|
196
|
+
params={"minDate": iso_timestamp},
|
|
197
|
+
)
|
|
198
|
+
response.raise_for_status()
|
|
199
|
+
if response.ok:
|
|
200
|
+
res = response.json()
|
|
201
|
+
events_counter = Counter(
|
|
202
|
+
[event.get("eventTypeName") for event in res.get("results", [])]
|
|
203
|
+
)
|
|
204
|
+
data = f"last 4 hours eventTypeName and # of occurrences list: {events_counter} \n to get more information about a given eventTypeName call atlas_return_events_type_from_project"
|
|
205
|
+
status = (
|
|
206
|
+
ToolResultStatus.SUCCESS
|
|
207
|
+
if events_counter
|
|
208
|
+
else ToolResultStatus.NO_DATA
|
|
209
|
+
)
|
|
210
|
+
return StructuredToolResult(status=status, data=data, params=params)
|
|
211
|
+
else:
|
|
212
|
+
return StructuredToolResult(
|
|
213
|
+
status=ToolResultStatus.ERROR,
|
|
214
|
+
error=f"Failed {self.name}. \n{response.text}",
|
|
215
|
+
return_code=response.status_code,
|
|
216
|
+
params=params,
|
|
217
|
+
)
|
|
218
|
+
except Exception as e:
|
|
219
|
+
logging.exception(self.get_parameterized_one_liner(params))
|
|
220
|
+
return StructuredToolResult(
|
|
221
|
+
status=ToolResultStatus.ERROR,
|
|
222
|
+
error=f"Exception {self.name}: {str(e)}",
|
|
223
|
+
params=params,
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
# https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/#tag/Monitoring-and-Logs/operation/getHostLogs
|
|
228
|
+
class ReturnLogsForProcessInProject(MongoDBAtlasBaseTool):
|
|
229
|
+
name: str = "atlas_return_logs_for_host_in_project"
|
|
230
|
+
description: str = "Returns log messages for the specified host for the specified project of the last 1 hour."
|
|
231
|
+
url: str = "https://cloud.mongodb.com/api/atlas/v2/groups/{project_id}/clusters/{process_id}/logs/mongodb.gz"
|
|
232
|
+
parameters: Dict[str, ToolParameter] = {
|
|
233
|
+
"hostName": ToolParameter(
|
|
234
|
+
description="The host must be the hostname, FQDN, IPv4 address, or IPv6 address of the host that runs the MongoDB process (mongod or mongos).",
|
|
235
|
+
type="string",
|
|
236
|
+
required=True,
|
|
237
|
+
),
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
def _invoke(self, params: Any) -> StructuredToolResult:
|
|
241
|
+
one_hour_ago = datetime.now(timezone.utc) - timedelta(hours=1)
|
|
242
|
+
try:
|
|
243
|
+
url = self.url.format(
|
|
244
|
+
project_id=self.toolset.config.get("project_id"),
|
|
245
|
+
process_id=params.get("hostName", ""),
|
|
246
|
+
)
|
|
247
|
+
response = self.toolset._session.get(
|
|
248
|
+
url=url,
|
|
249
|
+
headers={"Accept": "application/vnd.atlas.2025-03-12+gzip"},
|
|
250
|
+
params={"startDate": int(one_hour_ago.timestamp())},
|
|
251
|
+
)
|
|
252
|
+
response.raise_for_status()
|
|
253
|
+
if response.ok:
|
|
254
|
+
with gzip.GzipFile(fileobj=io.BytesIO(response.content)) as gz:
|
|
255
|
+
text_data = gz.read().decode("utf-8")
|
|
256
|
+
return StructuredToolResult(
|
|
257
|
+
status=ToolResultStatus.SUCCESS, data=text_data, params=params
|
|
258
|
+
)
|
|
259
|
+
else:
|
|
260
|
+
return StructuredToolResult(
|
|
261
|
+
status=ToolResultStatus.ERROR,
|
|
262
|
+
error=f"Failed {self.name}. \n{response.text}",
|
|
263
|
+
return_code=response.status_code,
|
|
264
|
+
params=params,
|
|
265
|
+
)
|
|
266
|
+
except Exception as e:
|
|
267
|
+
logging.exception(self.get_parameterized_one_liner(params))
|
|
268
|
+
return StructuredToolResult(
|
|
269
|
+
status=ToolResultStatus.ERROR,
|
|
270
|
+
error=f"Exception {self.name}: {str(e)}",
|
|
271
|
+
params=params,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/#tag/Events/operation/listProjectEvents
|
|
276
|
+
class ReturnEventTypeFromProject(MongoDBAtlasBaseTool):
|
|
277
|
+
name: str = "atlas_return_events_type_from_project"
|
|
278
|
+
description: str = "Returns all events of specific EventType for the specified project. can only query the last 4 hours."
|
|
279
|
+
url: str = "https://cloud.mongodb.com/api/atlas/v2/groups/{projectId}/events"
|
|
280
|
+
parameters: Dict[str, ToolParameter] = {
|
|
281
|
+
"eventType": ToolParameter(
|
|
282
|
+
description="A label of an eventType, all capital letters with snake case. examples: INSIDE_METRIC_THRESHOLD, PRIMARY_ELECTED and DATA_EXPLORER. NEVER call this before first calling atlas_return_events_from_project to get a list of last 4 hours eventTypes.",
|
|
283
|
+
type="string",
|
|
284
|
+
required=True,
|
|
285
|
+
),
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
def _invoke(self, params: Any) -> StructuredToolResult:
|
|
289
|
+
try:
|
|
290
|
+
url = self.url.format(projectId=self.toolset.config.get("project_id"))
|
|
291
|
+
|
|
292
|
+
now_utc = datetime.now(timezone.utc)
|
|
293
|
+
four_hours_ago = now_utc - timedelta(hours=4)
|
|
294
|
+
iso_timestamp = four_hours_ago.isoformat()
|
|
295
|
+
params.update({"itemsPerPage": 500, "minDate": iso_timestamp})
|
|
296
|
+
response = self.toolset._session.get(
|
|
297
|
+
url=url,
|
|
298
|
+
params=params,
|
|
299
|
+
)
|
|
300
|
+
return self.return_result(response, params)
|
|
301
|
+
except Exception as e:
|
|
302
|
+
logging.exception(self.get_parameterized_one_liner(params))
|
|
303
|
+
return StructuredToolResult(
|
|
304
|
+
status=ToolResultStatus.ERROR,
|
|
305
|
+
error=f"Exception {self.name}: {str(e)}",
|
|
306
|
+
params=params,
|
|
307
|
+
)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
toolsets:
|
|
2
|
+
aws/security:
|
|
3
|
+
description: "Set of tools to audit AWS security"
|
|
4
|
+
docs_url: "https://docs.robusta.dev/master/configuration/holmesgpt/toolsets/aws.html#security"
|
|
5
|
+
icon_url: "https://upload.wikimedia.org/wikipedia/commons/9/93/Amazon_Web_Services_Logo.svg"
|
|
6
|
+
tags:
|
|
7
|
+
- cli
|
|
8
|
+
prerequisites:
|
|
9
|
+
- command: "aws sts get-caller-identity"
|
|
10
|
+
|
|
11
|
+
tools:
|
|
12
|
+
- name: "aws_cloudtrail_event_lookup"
|
|
13
|
+
description: "Fetches events of a specified type from AWS CloudTrail along with the users that called them"
|
|
14
|
+
user_description: "get {{ EVENT_NAME }} events"
|
|
15
|
+
command: |
|
|
16
|
+
echo "EventName,EventId,EventTime,Username,AccessKeyId,ip,userID"
|
|
17
|
+
aws cloudtrail lookup-events \
|
|
18
|
+
--lookup-attributes AttributeKey=EventName,AttributeValue="{{ EVENT_NAME }}" \
|
|
19
|
+
--start-time $(date -v -7d -u +%Y-%m-%dT%H:%M:%SZ) \
|
|
20
|
+
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
|
|
21
|
+
--query 'Events[*].{EventName:EventName,EventId:EventId,EventTime:EventTime,Username:Username,AccessKeyId:AccessKeyId,ip:CloudTrailEvent.sourceIPAddress,userID:CloudTrailEvent.userIdentity.sessionContext.sessionIssuer.userName}' \
|
|
22
|
+
--output table
|
|
23
|
+
|
|
24
|
+
- name: "aws_cloudtrail_event_details"
|
|
25
|
+
description: "Fetches and returns full event details for an AWS cloudtrail event in JSON format given an event ID"
|
|
26
|
+
user_description: "looking up event {{ EVENT_ID }}"
|
|
27
|
+
command: |
|
|
28
|
+
aws cloudtrail lookup-events \
|
|
29
|
+
--lookup-attributes AttributeKey=EventId,AttributeValue="{{ EVENT_ID }}" \
|
|
30
|
+
--query 'Events[0]' --output json
|
|
31
|
+
|
|
32
|
+
- name: "aws_user_audit_logs"
|
|
33
|
+
description: "Fetches audit logs for a specified user from AWS CloudTrail in past 24 hours. Provide username as was outputed by aws_event_lookup or aws_event_details"
|
|
34
|
+
user_description: "get audit logs for {{ UserName }}"
|
|
35
|
+
command: |
|
|
36
|
+
aws cloudtrail lookup-events \
|
|
37
|
+
--lookup-attributes AttributeKey=Username,AttributeValue="{{ UserName }}" \
|
|
38
|
+
--start-time $(date -v -1d -u +%Y-%m-%dT%H:%M:%SZ) \
|
|
39
|
+
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
|
|
40
|
+
--query 'Events[*].{EventName:EventName,EventSource:EventSource,EventId:EventId,EventTime:EventTime,Username:Username,AccessKeyId:AccessKeyId,ip:CloudTrailEvent.sourceIPAddress,userID:CloudTrailEvent.userIdentity.sessionContext.sessionIssuer.userName}' \
|
|
41
|
+
--output table
|
|
42
|
+
|
|
43
|
+
aws/rds:
|
|
44
|
+
description: "Read access to Amazon RDS resources"
|
|
45
|
+
docs_url: "https://docs.robusta.dev/master/configuration/holmesgpt/toolsets/aws.html#rds"
|
|
46
|
+
icon_url: "https://upload.wikimedia.org/wikipedia/commons/9/93/Amazon_Web_Services_Logo.svg"
|
|
47
|
+
tags:
|
|
48
|
+
- cli
|
|
49
|
+
prerequisites:
|
|
50
|
+
- command: "aws sts get-caller-identity"
|
|
51
|
+
|
|
52
|
+
tools:
|
|
53
|
+
- name: "aws_rds_describe_events"
|
|
54
|
+
description: "Runs aws rds describe-events"
|
|
55
|
+
user_description: "fetch rds events"
|
|
56
|
+
command: "aws rds describe-events"
|
|
57
|
+
|
|
58
|
+
- name: "aws_rds_describe_instance"
|
|
59
|
+
description: "Get the configuration of a RDS instance"
|
|
60
|
+
user_description: "Get the configuration of a RDS instance"
|
|
61
|
+
command: "aws rds describe-db-instances --db-instance-identifier '{{ db_instance_identifier }}'"
|
|
62
|
+
|
|
63
|
+
- name: "aws_rds_describe_instances"
|
|
64
|
+
description: "Runs aws rds describe-db-instances"
|
|
65
|
+
user_description: "fetch rds instances"
|
|
66
|
+
command: "aws rds describe-db-instances"
|
|
67
|
+
|
|
68
|
+
- name: "aws_rds_describe_logs"
|
|
69
|
+
description: "Describe all available logs for an AWS RDS instance."
|
|
70
|
+
user_description: "list available RDS logs (e.g. slow query logs)"
|
|
71
|
+
command: "aws rds describe-db-log-files --db-instance-identifier '{{ db_instance_identifier }}'"
|
|
72
|
+
|
|
73
|
+
- name: "aws_rds_fetch_log_by_name"
|
|
74
|
+
description: "Fetch a specific log for an AWS RDS instance by log file name."
|
|
75
|
+
user_description: "fetch a specific RDS log"
|
|
76
|
+
command: "aws rds download-db-log-file-portion --db-instance-identifier '{{ db_instance_identifier }}' --log-file-name '{{ log_file_name }}' --starting-token 0"
|
|
File without changes
|