mcp-instana 0.1.0__py3-none-any.whl → 0.1.1__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.
- mcp_instana-0.1.1.dist-info/METADATA +908 -0
- mcp_instana-0.1.1.dist-info/RECORD +30 -0
- {mcp_instana-0.1.0.dist-info → mcp_instana-0.1.1.dist-info}/WHEEL +1 -1
- mcp_instana-0.1.1.dist-info/entry_points.txt +4 -0
- mcp_instana-0.1.0.dist-info/LICENSE → mcp_instana-0.1.1.dist-info/licenses/LICENSE.md +3 -3
- src/application/__init__.py +1 -0
- src/{client/application_alert_config_mcp_tools.py → application/application_alert_config.py} +251 -273
- src/application/application_analyze.py +415 -0
- src/application/application_catalog.py +153 -0
- src/{client/application_metrics_mcp_tools.py → application/application_metrics.py} +107 -129
- src/{client/application_resources_mcp_tools.py → application/application_resources.py} +128 -150
- src/application/application_settings.py +1135 -0
- src/application/application_topology.py +107 -0
- src/core/__init__.py +1 -0
- src/core/server.py +436 -0
- src/core/utils.py +213 -0
- src/event/__init__.py +1 -0
- src/{client/events_mcp_tools.py → event/events_tools.py} +128 -136
- src/infrastructure/__init__.py +1 -0
- src/{client/infrastructure_analyze_mcp_tools.py → infrastructure/infrastructure_analyze.py} +200 -203
- src/{client/infrastructure_catalog_mcp_tools.py → infrastructure/infrastructure_catalog.py} +194 -264
- src/infrastructure/infrastructure_metrics.py +167 -0
- src/{client/infrastructure_resources_mcp_tools.py → infrastructure/infrastructure_resources.py} +192 -223
- src/{client/infrastructure_topology_mcp_tools.py → infrastructure/infrastructure_topology.py} +105 -106
- src/log/__init__.py +1 -0
- src/log/log_alert_configuration.py +331 -0
- src/prompts/mcp_prompts.py +900 -0
- src/prompts/prompt_loader.py +29 -0
- src/prompts/prompt_registry.json +21 -0
- mcp_instana-0.1.0.dist-info/METADATA +0 -649
- mcp_instana-0.1.0.dist-info/RECORD +0 -19
- mcp_instana-0.1.0.dist-info/entry_points.txt +0 -3
- src/client/What is the sum of queue depth for all q +0 -55
- src/client/instana_client_base.py +0 -93
- src/client/log_alert_configuration_mcp_tools.py +0 -316
- src/client/show the top 5 services with the highest +0 -28
- src/mcp_server.py +0 -343
|
@@ -0,0 +1,1135 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Application Settings MCP Tools Module
|
|
3
|
+
|
|
4
|
+
This module provides application settings-specific MCP tools for Instana monitoring.
|
|
5
|
+
|
|
6
|
+
The API endpoints of this group provides a way to create, read, update, delete (CRUD) for various configuration settings.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import re
|
|
10
|
+
import sys
|
|
11
|
+
import traceback
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from typing import Any, Dict, List, Optional
|
|
14
|
+
|
|
15
|
+
from src.core.utils import BaseInstanaClient, register_as_tool, with_header_auth
|
|
16
|
+
|
|
17
|
+
# Import the necessary classes from the SDK
|
|
18
|
+
try:
|
|
19
|
+
from instana_client.api.application_settings_api import ApplicationSettingsApi
|
|
20
|
+
from instana_client.api_client import ApiClient
|
|
21
|
+
from instana_client.configuration import Configuration
|
|
22
|
+
from instana_client.models.application_config import ApplicationConfig
|
|
23
|
+
from instana_client.models.endpoint_config import EndpointConfig
|
|
24
|
+
from instana_client.models.manual_service_config import ManualServiceConfig
|
|
25
|
+
from instana_client.models.new_application_config import NewApplicationConfig
|
|
26
|
+
from instana_client.models.new_manual_service_config import NewManualServiceConfig
|
|
27
|
+
from instana_client.models.service_config import ServiceConfig
|
|
28
|
+
except ImportError as e:
|
|
29
|
+
print(f"Error importing Instana SDK: {e}", file=sys.stderr)
|
|
30
|
+
traceback.print_exc(file=sys.stderr)
|
|
31
|
+
raise
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Helper function for debug printing
|
|
35
|
+
def debug_print(*args, **kwargs):
|
|
36
|
+
"""Print debug information to stderr instead of stdout"""
|
|
37
|
+
print(*args, file=sys.stderr, **kwargs)
|
|
38
|
+
|
|
39
|
+
class ApplicationSettingsMCPTools(BaseInstanaClient):
|
|
40
|
+
"""Tools for application settings in Instana MCP."""
|
|
41
|
+
|
|
42
|
+
def __init__(self, read_token: str, base_url: str):
|
|
43
|
+
"""Initialize the Application Settings MCP tools client."""
|
|
44
|
+
super().__init__(read_token=read_token, base_url=base_url)
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
|
|
48
|
+
# Configure the API client with the correct base URL and authentication
|
|
49
|
+
configuration = Configuration()
|
|
50
|
+
configuration.host = base_url
|
|
51
|
+
configuration.api_key['ApiKeyAuth'] = read_token
|
|
52
|
+
configuration.api_key_prefix['ApiKeyAuth'] = 'apiToken'
|
|
53
|
+
|
|
54
|
+
# Create an API client with this configuration
|
|
55
|
+
api_client = ApiClient(configuration=configuration)
|
|
56
|
+
|
|
57
|
+
# Initialize the Instana SDK's ApplicationSettingsApi with our configured client
|
|
58
|
+
self.settings_api = ApplicationSettingsApi(api_client=api_client)
|
|
59
|
+
except Exception as e:
|
|
60
|
+
debug_print(f"Error initializing ApplicationSettingsApi: {e}")
|
|
61
|
+
traceback.print_exc(file=sys.stderr)
|
|
62
|
+
raise
|
|
63
|
+
|
|
64
|
+
@register_as_tool
|
|
65
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
66
|
+
async def get_all_applications_configs(self,
|
|
67
|
+
ctx=None,
|
|
68
|
+
api_client=None) -> List[Dict[str, Any]]:
|
|
69
|
+
"""
|
|
70
|
+
All Application Perspectives Configuration
|
|
71
|
+
Get a list of all Application Perspectives with their configuration settings.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
ctx: The MCP context (optional)
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Dictionary containing endpoints data or error information
|
|
78
|
+
"""
|
|
79
|
+
try:
|
|
80
|
+
debug_print("Fetching all applications and their settings")
|
|
81
|
+
result = api_client.get_application_configs()
|
|
82
|
+
# Convert the result to a list of dictionaries
|
|
83
|
+
if isinstance(result, list):
|
|
84
|
+
result_dict = [item.to_dict() if hasattr(item, 'to_dict') else item for item in result]
|
|
85
|
+
elif hasattr(result, 'to_dict'):
|
|
86
|
+
result_dict = result.to_dict()
|
|
87
|
+
else:
|
|
88
|
+
result_dict = result
|
|
89
|
+
|
|
90
|
+
debug_print(f"Result from get_application_configs: {result_dict}")
|
|
91
|
+
return result_dict
|
|
92
|
+
|
|
93
|
+
except Exception as e:
|
|
94
|
+
debug_print(f"Error in get_application_configs: {e}")
|
|
95
|
+
traceback.print_exc(file=sys.stderr)
|
|
96
|
+
return [{"error": f"Failed to get all applications: {e!s}"}]
|
|
97
|
+
|
|
98
|
+
@register_as_tool
|
|
99
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
100
|
+
async def add_application_config(self,
|
|
101
|
+
access_rules: List[Dict[str, str]],
|
|
102
|
+
boundary_scope: str,
|
|
103
|
+
label: str,
|
|
104
|
+
scope: str,
|
|
105
|
+
tag_filter_expression: Optional[List[Dict[str, str]]] = None,
|
|
106
|
+
ctx=None,
|
|
107
|
+
api_client=None) -> Dict[str, Any]:
|
|
108
|
+
"""
|
|
109
|
+
Add a new Application Perspective configuration.
|
|
110
|
+
This tool allows you to create a new Application Perspective with specified settings.
|
|
111
|
+
Args:
|
|
112
|
+
accessRules: List of access rules for the application perspective
|
|
113
|
+
boundaryScope: Boundary scope for the application perspective
|
|
114
|
+
label: Label for the application perspective
|
|
115
|
+
scope: Scope of the application perspective
|
|
116
|
+
tagFilterExpression: Tag filter expression for the application perspective (Optional)
|
|
117
|
+
ctx: The MCP context (optional)
|
|
118
|
+
Returns:
|
|
119
|
+
Dictionary containing the created application perspective configuration or error information
|
|
120
|
+
"""
|
|
121
|
+
try:
|
|
122
|
+
debug_print("Adding new application perspective configuration")
|
|
123
|
+
if not (access_rules or boundary_scope or label or scope):
|
|
124
|
+
return {"error": "Required enitities are missing or invalid"}
|
|
125
|
+
|
|
126
|
+
# Create a NewApplicationConfig instance with the provided parameters
|
|
127
|
+
request_body = {
|
|
128
|
+
"access_rules": access_rules,
|
|
129
|
+
"boundary_scope": boundary_scope,
|
|
130
|
+
"label": label,
|
|
131
|
+
"scope": scope,
|
|
132
|
+
"tag_filter_expression": tag_filter_expression
|
|
133
|
+
}
|
|
134
|
+
new_application_config = NewApplicationConfig(**request_body)
|
|
135
|
+
debug_print(f"New Application Config: {new_application_config.to_dict()}")
|
|
136
|
+
|
|
137
|
+
# Call the add_application_config method from the SDK
|
|
138
|
+
result = api_client.add_application_config(
|
|
139
|
+
new_application_config=new_application_config
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# Convert the result to a dictionary
|
|
143
|
+
if hasattr(result, 'to_dict'):
|
|
144
|
+
result_dict = result.to_dict()
|
|
145
|
+
else:
|
|
146
|
+
result_dict = result
|
|
147
|
+
|
|
148
|
+
debug_print(f"Result from add_application_config: {result_dict}")
|
|
149
|
+
return result_dict
|
|
150
|
+
except Exception as e:
|
|
151
|
+
debug_print(f"Error in add_application_config: {e}")
|
|
152
|
+
traceback.print_exc(file=sys.stderr)
|
|
153
|
+
return {"error": f"Failed to add application configuration: {e!s}"}
|
|
154
|
+
|
|
155
|
+
@register_as_tool
|
|
156
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
157
|
+
async def delete_application_config(self,
|
|
158
|
+
id: str,
|
|
159
|
+
ctx=None,
|
|
160
|
+
api_client=None) -> Dict[str, Any]:
|
|
161
|
+
"""
|
|
162
|
+
Delete an Application Perspective configuration.
|
|
163
|
+
This tool allows you to delete an existing Application Perspective by its ID.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
application_id: The ID of the application perspective to delete
|
|
167
|
+
ctx: The MCP context (optional)
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
Dictionary containing the result of the deletion or error information
|
|
171
|
+
"""
|
|
172
|
+
try:
|
|
173
|
+
if not id:
|
|
174
|
+
return {"error": "Application perspective ID is required for deletion"}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
debug_print(f"Deleting application perspective with ID: {id}")
|
|
178
|
+
# Call the delete_application_config method from the SDK
|
|
179
|
+
self.settings_api.delete_application_config(id=id)
|
|
180
|
+
|
|
181
|
+
result_dict = {
|
|
182
|
+
"success": True,
|
|
183
|
+
"message": f"Application Confiuguration '{id}' has been successfully deleted"
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
debug_print(f"Successfully deleted application perspective with ID: {id}")
|
|
187
|
+
return result_dict
|
|
188
|
+
except Exception as e:
|
|
189
|
+
debug_print(f"Error in delete_application_config: {e}")
|
|
190
|
+
traceback.print_exc(file=sys.stderr)
|
|
191
|
+
return {"error": f"Failed to delete application configuration: {e!s}"}
|
|
192
|
+
|
|
193
|
+
@register_as_tool
|
|
194
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
195
|
+
async def get_application_config(self,
|
|
196
|
+
id: str,
|
|
197
|
+
ctx=None,
|
|
198
|
+
api_client=None) -> Dict[str, Any]:
|
|
199
|
+
"""
|
|
200
|
+
Get an Application Perspective configuration by ID.
|
|
201
|
+
This tool retrieves the configuration settings for a specific Application Perspective.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
id: The ID of the application perspective to retrieve
|
|
205
|
+
ctx: The MCP context (optional)
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
Dictionary containing the application perspective configuration or error information
|
|
209
|
+
"""
|
|
210
|
+
try:
|
|
211
|
+
debug_print(f"Fetching application perspective with ID: {id}")
|
|
212
|
+
# Call the get_application_config method from the SDK
|
|
213
|
+
result = api_client.get_application_config(id=id)
|
|
214
|
+
|
|
215
|
+
# Convert the result to a dictionary
|
|
216
|
+
if hasattr(result, 'to_dict'):
|
|
217
|
+
result_dict = result.to_dict()
|
|
218
|
+
else:
|
|
219
|
+
result_dict = result
|
|
220
|
+
|
|
221
|
+
debug_print(f"Result from get_application_config: {result_dict}")
|
|
222
|
+
return result_dict
|
|
223
|
+
except Exception as e:
|
|
224
|
+
debug_print(f"Error in get_application_config: {e}")
|
|
225
|
+
traceback.print_exc(file=sys.stderr)
|
|
226
|
+
return {"error": f"Failed to get application configuration: {e!s}"}
|
|
227
|
+
|
|
228
|
+
@register_as_tool
|
|
229
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
230
|
+
async def update_application_config(
|
|
231
|
+
self,
|
|
232
|
+
id: str,
|
|
233
|
+
access_rules: List[Dict[str, str]],
|
|
234
|
+
boundary_scope: str,
|
|
235
|
+
label: str,
|
|
236
|
+
scope: str,
|
|
237
|
+
tag_filter_expression: Optional[List[Dict[str, str]]] = None,
|
|
238
|
+
match_specification: Optional[List[Dict[str, Any]]] = None,
|
|
239
|
+
ctx=None,
|
|
240
|
+
api_client=None
|
|
241
|
+
) -> Dict[str, Any]:
|
|
242
|
+
"""
|
|
243
|
+
Update an existing Application Perspective configuration.
|
|
244
|
+
This tool allows you to update an existing Application Perspective with specified application Id.
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
id: The ID of the application perspective to retrieve
|
|
248
|
+
access_rules: List of access rules for the application perspective
|
|
249
|
+
boundary_scope: Boundary scope for the application perspective
|
|
250
|
+
label: Label for the application perspective
|
|
251
|
+
scope: Scope of the application perspective
|
|
252
|
+
tag_filter_expression: Tag filter expression for the application perspective (Optional)
|
|
253
|
+
ctx: The MCP context (optional)
|
|
254
|
+
Returns:
|
|
255
|
+
Dictionary containing the created application perspective configuration or error information
|
|
256
|
+
"""
|
|
257
|
+
|
|
258
|
+
try:
|
|
259
|
+
debug_print("Update existing application perspective configuration")
|
|
260
|
+
if not (access_rules or boundary_scope or label or scope or id):
|
|
261
|
+
return {"error": "Required enitities are missing or invalid"}
|
|
262
|
+
|
|
263
|
+
request_body = {
|
|
264
|
+
"access_rules": access_rules,
|
|
265
|
+
"boundary_scope": boundary_scope,
|
|
266
|
+
"id": id,
|
|
267
|
+
"label": label,
|
|
268
|
+
"match_specification": match_specification,
|
|
269
|
+
"scope": scope,
|
|
270
|
+
"tag_filter_expression": tag_filter_expression
|
|
271
|
+
}
|
|
272
|
+
# Create a ApplicationConfig instance with the provided parameters
|
|
273
|
+
application_config = ApplicationConfig(**request_body)
|
|
274
|
+
debug_print(f"Application Config: {application_config.to_dict()}")
|
|
275
|
+
|
|
276
|
+
# Call the put_application_config method from the SDK
|
|
277
|
+
result = api_client.put_application_config(
|
|
278
|
+
id=id,
|
|
279
|
+
application_config=application_config
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
# Convert the result to a dictionary
|
|
283
|
+
if hasattr(result, 'to_dict'):
|
|
284
|
+
result_dict = result.to_dict()
|
|
285
|
+
else:
|
|
286
|
+
result_dict = result
|
|
287
|
+
|
|
288
|
+
debug_print(f"Result from put_application_config: {result_dict}")
|
|
289
|
+
return result_dict
|
|
290
|
+
except Exception as e:
|
|
291
|
+
debug_print(f"Error in put_application_config: {e}")
|
|
292
|
+
traceback.print_exc(file=sys.stderr)
|
|
293
|
+
return {"error": f"Failed to update application configuration: {e!s}"}
|
|
294
|
+
|
|
295
|
+
@register_as_tool
|
|
296
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
297
|
+
async def get_all_endpoint_configs(self,
|
|
298
|
+
ctx=None,
|
|
299
|
+
api_client=None) -> List[Dict[str, Any]]:
|
|
300
|
+
"""
|
|
301
|
+
All Endpoint Perspectives Configuration
|
|
302
|
+
Get a list of all Endpoint Perspectives with their configuration settings.
|
|
303
|
+
Args:
|
|
304
|
+
ctx: The MCP context (optional)
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
Dictionary containing endpoints data or error information
|
|
308
|
+
"""
|
|
309
|
+
try:
|
|
310
|
+
debug_print("Fetching all endpoint configs")
|
|
311
|
+
result = api_client.get_endpoint_configs()
|
|
312
|
+
# Convert the result to a dictionary
|
|
313
|
+
if hasattr(result, 'to_dict'):
|
|
314
|
+
result_dict = result.to_dict()
|
|
315
|
+
else:
|
|
316
|
+
# If it's already a dict or another format, use it as is
|
|
317
|
+
result_dict = result
|
|
318
|
+
|
|
319
|
+
debug_print(f"Result from get_endpoint_configs: {result_dict}")
|
|
320
|
+
return result_dict
|
|
321
|
+
|
|
322
|
+
except Exception as e:
|
|
323
|
+
debug_print(f"Error in get_endpoint_configs: {e}")
|
|
324
|
+
traceback.print_exc(file=sys.stderr)
|
|
325
|
+
return [{"error": f"Failed to get endpoint configs: {e!s}"}]
|
|
326
|
+
|
|
327
|
+
@register_as_tool
|
|
328
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
329
|
+
async def create_endpoint_config(
|
|
330
|
+
self,
|
|
331
|
+
endpoint_case: str,
|
|
332
|
+
service_id: str,
|
|
333
|
+
endpoint_name_by_collected_path_template_rule_enabled: Optional[bool]= None,
|
|
334
|
+
endpoint_name_by_first_path_segment_rule_enabled: Optional[bool] = None,
|
|
335
|
+
rules: Optional[List[Dict[str, Any]]] = None,
|
|
336
|
+
ctx=None,
|
|
337
|
+
api_client=None
|
|
338
|
+
) -> Dict[str, Any]:
|
|
339
|
+
"""
|
|
340
|
+
Create or update endpoint configuration for a service.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
serviceId (str): Instana Service ID to configure.
|
|
344
|
+
endpointCase (str): Case format for endpoints. One of: 'ORIGINAL', 'LOWER', 'UPPER'.
|
|
345
|
+
endpointNameByCollectedPathTemplateRuleEnabled (Optional[bool]): Enable path template rule. (Optional)
|
|
346
|
+
endpointNameByFirstPathSegmentRuleEnabled (Optional[bool]): Enable first path segment rule. (Optional)
|
|
347
|
+
rules (Optional[List[Dict[str, Any]]]): Optional list of custom HTTP endpoint rules. (Optional)
|
|
348
|
+
ctx: The MCP context (optional)
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
Dict[str, Any]: Response from the create/update endpoint configuration API.
|
|
352
|
+
"""
|
|
353
|
+
try:
|
|
354
|
+
debug_print("Creating endpoint configs")
|
|
355
|
+
if not endpoint_case or not service_id:
|
|
356
|
+
return {"error": "Required enitities are missing or invalid"}
|
|
357
|
+
|
|
358
|
+
request_body = {
|
|
359
|
+
"endpoint_case": endpoint_case,
|
|
360
|
+
"endpoint_name_by_collected_path_template_rule_enabled": endpoint_name_by_collected_path_template_rule_enabled,
|
|
361
|
+
"endpoint_name_by_first_path_segment_rule_enabled": endpoint_name_by_first_path_segment_rule_enabled,
|
|
362
|
+
"rules": rules,
|
|
363
|
+
"serviceId": service_id
|
|
364
|
+
}
|
|
365
|
+
endpoint_config = EndpointConfig(**request_body)
|
|
366
|
+
|
|
367
|
+
result = api_client.create_endpoint_config(
|
|
368
|
+
endpoint_config=endpoint_config
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
# Convert the result to a dictionary
|
|
372
|
+
if hasattr(result, 'to_dict'):
|
|
373
|
+
result_dict = result.to_dict()
|
|
374
|
+
else:
|
|
375
|
+
# If it's already a dict or another format, use it as is
|
|
376
|
+
result_dict = result
|
|
377
|
+
|
|
378
|
+
debug_print(f"Result from get_endpoint_configs: {result_dict}")
|
|
379
|
+
return result_dict
|
|
380
|
+
|
|
381
|
+
except Exception as e:
|
|
382
|
+
debug_print(f"Error in get_endpoint_configs: {e}")
|
|
383
|
+
traceback.print_exc(file=sys.stderr)
|
|
384
|
+
return {"error": f"Failed to get endpoint configs: {e!s}"}
|
|
385
|
+
|
|
386
|
+
@register_as_tool
|
|
387
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
388
|
+
async def delete_endpoint_config(
|
|
389
|
+
self,
|
|
390
|
+
id: str,
|
|
391
|
+
ctx=None,
|
|
392
|
+
api_client=None
|
|
393
|
+
) -> Dict[str, Any]:
|
|
394
|
+
"""
|
|
395
|
+
Delete an endpoint configuration of a service.
|
|
396
|
+
|
|
397
|
+
Args:
|
|
398
|
+
id: An Instana generated unique identifier for a Service.
|
|
399
|
+
ctx: The MCP context (optional)
|
|
400
|
+
|
|
401
|
+
Returns:
|
|
402
|
+
Dict[str, Any]: Response from the delete endpoint configuration API.
|
|
403
|
+
"""
|
|
404
|
+
try:
|
|
405
|
+
debug_print("Delete endpoint configs")
|
|
406
|
+
if not id:
|
|
407
|
+
return {"error": "Required enitities are missing or invalid"}
|
|
408
|
+
|
|
409
|
+
api_client.delete_endpoint_config(id=id)
|
|
410
|
+
|
|
411
|
+
result_dict = {
|
|
412
|
+
"success": True,
|
|
413
|
+
"message": f"Endpoint Confiuguration '{id}' has been successfully deleted"
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
debug_print(f"Successfully deleted endpoint perspective with ID: {id}")
|
|
417
|
+
return result_dict
|
|
418
|
+
|
|
419
|
+
except Exception as e:
|
|
420
|
+
debug_print(f"Error in delete_endpoint_config: {e}")
|
|
421
|
+
traceback.print_exc(file=sys.stderr)
|
|
422
|
+
return {"error": f"Failed to delete endpoint configs: {e!s}"}
|
|
423
|
+
|
|
424
|
+
@register_as_tool
|
|
425
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
426
|
+
async def get_endpoint_config(
|
|
427
|
+
self,
|
|
428
|
+
id: str,
|
|
429
|
+
ctx=None,
|
|
430
|
+
api_client=None
|
|
431
|
+
) -> Dict[str, Any]:
|
|
432
|
+
"""
|
|
433
|
+
This MCP tool is used for endpoint if one wants to retrieve the endpoint configuration of a service.
|
|
434
|
+
Args:
|
|
435
|
+
id: An Instana generated unique identifier for a Service.
|
|
436
|
+
ctx: The MCP context (optional)
|
|
437
|
+
|
|
438
|
+
Returns:
|
|
439
|
+
Dict[str, Any]: Response from the create/update endpoint configuration API.
|
|
440
|
+
|
|
441
|
+
"""
|
|
442
|
+
try:
|
|
443
|
+
debug_print("get endpoint config")
|
|
444
|
+
if not id:
|
|
445
|
+
return {"error": "Required enitities are missing or invalid"}
|
|
446
|
+
|
|
447
|
+
result = api_client.get_endpoint_config(
|
|
448
|
+
id=id
|
|
449
|
+
)
|
|
450
|
+
# Convert the result to a dictionary
|
|
451
|
+
if hasattr(result, 'to_dict'):
|
|
452
|
+
result_dict = result.to_dict()
|
|
453
|
+
else:
|
|
454
|
+
# If it's already a dict or another format, use it as is
|
|
455
|
+
result_dict = result
|
|
456
|
+
|
|
457
|
+
debug_print(f"Result from get_endpoint_configs: {result_dict}")
|
|
458
|
+
return result_dict
|
|
459
|
+
except Exception as e:
|
|
460
|
+
debug_print(f"Error in get_endpoint_configs: {e}")
|
|
461
|
+
traceback.print_exc(file=sys.stderr)
|
|
462
|
+
return {"error": f"Failed to get endpoint configs: {e!s}"}
|
|
463
|
+
|
|
464
|
+
@register_as_tool
|
|
465
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
466
|
+
async def update_endpoint_config(
|
|
467
|
+
self,
|
|
468
|
+
id: str,
|
|
469
|
+
endpoint_case: str,
|
|
470
|
+
service_id: str,
|
|
471
|
+
endpoint_name_by_collected_path_template_rule_enabled: Optional[bool]= None,
|
|
472
|
+
endpoint_name_by_first_path_segment_rule_enabled: Optional[bool] = None,
|
|
473
|
+
rules: Optional[List[Dict[str, Any]]] = None,
|
|
474
|
+
ctx=None,
|
|
475
|
+
api_client=None
|
|
476
|
+
) -> Dict[str, Any]:
|
|
477
|
+
"""
|
|
478
|
+
update endpoint configuration for a service.
|
|
479
|
+
|
|
480
|
+
Args:
|
|
481
|
+
id: An Instana generated unique identifier for a Service.
|
|
482
|
+
serviceId: Instana Service ID to configure.
|
|
483
|
+
endpointCase: Case format for endpoints. One of: 'ORIGINAL', 'LOWER', 'UPPER'.
|
|
484
|
+
endpointNameByCollectedPathTemplateRuleEnabled: Enable path template rule. (Optional)
|
|
485
|
+
endpointNameByFirstPathSegmentRuleEnabled: Enable first path segment rule. (Optional)
|
|
486
|
+
rules: Optional list of custom HTTP endpoint rules. (Optional)
|
|
487
|
+
ctx: The MCP context (optional)
|
|
488
|
+
|
|
489
|
+
Returns:
|
|
490
|
+
Dict[str, Any]: Response from the create/update endpoint configuration API.
|
|
491
|
+
"""
|
|
492
|
+
try:
|
|
493
|
+
debug_print("Updating endpoint configs")
|
|
494
|
+
if not endpoint_case or not service_id:
|
|
495
|
+
return {"error": "Required enitities are missing or invalid"}
|
|
496
|
+
|
|
497
|
+
request_body = {
|
|
498
|
+
"endpoint_case": endpoint_case,
|
|
499
|
+
"endpoint_name_by_collected_path_template_rule_enabled": endpoint_name_by_collected_path_template_rule_enabled,
|
|
500
|
+
"endpoint_name_by_first_path_segment_rule_enabled": endpoint_name_by_first_path_segment_rule_enabled,
|
|
501
|
+
"rules": rules,
|
|
502
|
+
"serviceId": service_id
|
|
503
|
+
}
|
|
504
|
+
endpoint_config = EndpointConfig(**request_body)
|
|
505
|
+
|
|
506
|
+
result = api_client.update_endpoint_config(
|
|
507
|
+
id=id,
|
|
508
|
+
endpoint_config=endpoint_config
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
# Convert the result to a dictionary
|
|
512
|
+
if hasattr(result, 'to_dict'):
|
|
513
|
+
result_dict = result.to_dict()
|
|
514
|
+
else:
|
|
515
|
+
# If it's already a dict or another format, use it as is
|
|
516
|
+
result_dict = result
|
|
517
|
+
|
|
518
|
+
debug_print(f"Result from get_endpoint_configs: {result_dict}")
|
|
519
|
+
return result_dict
|
|
520
|
+
|
|
521
|
+
except Exception as e:
|
|
522
|
+
debug_print(f"Error in get_endpoint_configs: {e}")
|
|
523
|
+
traceback.print_exc(file=sys.stderr)
|
|
524
|
+
return {"error": f"Failed to get endpoint configs: {e!s}"}
|
|
525
|
+
|
|
526
|
+
@register_as_tool
|
|
527
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
528
|
+
async def get_all_manual_service_configs(self,
|
|
529
|
+
ctx=None,
|
|
530
|
+
api_client=None) -> List[Dict[str, Any]]:
|
|
531
|
+
"""
|
|
532
|
+
All Manual Service Perspectives Configuration
|
|
533
|
+
Get a list of all Manual Service Perspectives with their configuration settings.
|
|
534
|
+
Args:
|
|
535
|
+
ctx: The MCP context (optional)
|
|
536
|
+
|
|
537
|
+
Returns:
|
|
538
|
+
Dictionary containing endpoints data or error information
|
|
539
|
+
"""
|
|
540
|
+
try:
|
|
541
|
+
debug_print("Fetching all manual configs")
|
|
542
|
+
result = api_client.get_all_manual_service_configs()
|
|
543
|
+
# Convert the result to a dictionary
|
|
544
|
+
if hasattr(result, 'to_dict'):
|
|
545
|
+
result_dict = result.to_dict()
|
|
546
|
+
else:
|
|
547
|
+
# If it's already a dict or another format, use it as is
|
|
548
|
+
result_dict = result
|
|
549
|
+
|
|
550
|
+
debug_print(f"Result from get_all_manual_service_configs: {result_dict}")
|
|
551
|
+
return result_dict
|
|
552
|
+
|
|
553
|
+
except Exception as e:
|
|
554
|
+
debug_print(f"Error in get_all_manual_service_configs: {e}")
|
|
555
|
+
traceback.print_exc(file=sys.stderr)
|
|
556
|
+
return [{"error": f"Failed to get manual service configs: {e!s}"}]
|
|
557
|
+
|
|
558
|
+
@register_as_tool
|
|
559
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
560
|
+
async def add_manual_service_config(
|
|
561
|
+
self,
|
|
562
|
+
tagFilterExpression: Dict[str, Any],
|
|
563
|
+
unmonitoredServiceName: Optional[str] = None,
|
|
564
|
+
existingServiceId: Optional[str] = None,
|
|
565
|
+
description: Optional[str] = None,
|
|
566
|
+
enabled: Optional[bool] = True,
|
|
567
|
+
ctx=None,
|
|
568
|
+
api_client=None
|
|
569
|
+
) -> Dict[str, Any]:
|
|
570
|
+
"""
|
|
571
|
+
Create a manual service mapping configuration.
|
|
572
|
+
|
|
573
|
+
Requires `CanConfigureServiceMapping` permission on the API token.
|
|
574
|
+
|
|
575
|
+
Args:
|
|
576
|
+
tagFilterExpression : Boolean expression of tag filters to match relevant calls.
|
|
577
|
+
unmonitoredServiceName : Custom name for an unmonitored service to map. (Optional)
|
|
578
|
+
existingServiceId : Service ID to link the matched calls to. (Optional)
|
|
579
|
+
description : Description of the mapping configuration. (Optional)
|
|
580
|
+
enabled : Enable or disable the configuration. Defaults to True. (Optional)
|
|
581
|
+
ctx: Optional execution context.
|
|
582
|
+
|
|
583
|
+
Returns:
|
|
584
|
+
Dict[str, Any]: API response indicating success or failure.
|
|
585
|
+
"""
|
|
586
|
+
try:
|
|
587
|
+
debug_print("Creating manual service configuration")
|
|
588
|
+
|
|
589
|
+
if not (unmonitoredServiceName and existingServiceId):
|
|
590
|
+
return {
|
|
591
|
+
"error": "You must provide either 'unmonitoredServiceName' or 'existingServiceId'."
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
if not tagFilterExpression:
|
|
595
|
+
return {"error": "Required enitities are missing or invalid"}
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
body = {
|
|
599
|
+
"tagFilterExpression": tagFilterExpression,
|
|
600
|
+
"enabled": enabled
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
if unmonitoredServiceName:
|
|
604
|
+
body["unmonitoredServiceName"] = unmonitoredServiceName
|
|
605
|
+
if existingServiceId:
|
|
606
|
+
body["existingServiceId"] = existingServiceId
|
|
607
|
+
if description:
|
|
608
|
+
body["description"] = description
|
|
609
|
+
|
|
610
|
+
new_manual_service_config = NewManualServiceConfig(**body)
|
|
611
|
+
|
|
612
|
+
result = api_client.add_manual_service_config(
|
|
613
|
+
new_manual_service_config=new_manual_service_config
|
|
614
|
+
)
|
|
615
|
+
|
|
616
|
+
if hasattr(result, "to_dict"):
|
|
617
|
+
result_dict = result.to_dict()
|
|
618
|
+
else:
|
|
619
|
+
result_dict = result
|
|
620
|
+
|
|
621
|
+
debug_print(f"Manual service configuration result: {result_dict}")
|
|
622
|
+
return result_dict
|
|
623
|
+
|
|
624
|
+
except Exception as e:
|
|
625
|
+
debug_print(f"Error creating manual service configuration: {e}")
|
|
626
|
+
traceback.print_exc(file=sys.stderr)
|
|
627
|
+
return {"error": f"Failed to create manual service configuration: {e!s}"}
|
|
628
|
+
|
|
629
|
+
@register_as_tool
|
|
630
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
631
|
+
async def delete_manual_service_config(
|
|
632
|
+
self,
|
|
633
|
+
id: str,
|
|
634
|
+
ctx=None,
|
|
635
|
+
api_client=None
|
|
636
|
+
) -> Dict[str, Any]:
|
|
637
|
+
"""
|
|
638
|
+
Delete a manual service configuration.
|
|
639
|
+
|
|
640
|
+
Args:
|
|
641
|
+
id: A unique id of the manual service configuration.
|
|
642
|
+
ctx: The MCP context (optional)
|
|
643
|
+
|
|
644
|
+
Returns:
|
|
645
|
+
Dict[str, Any]: Response from the delete manual service configuration API.
|
|
646
|
+
"""
|
|
647
|
+
try:
|
|
648
|
+
debug_print("Delete manual service configs")
|
|
649
|
+
if not id:
|
|
650
|
+
return {"error": "Required enitities are missing or invalid"}
|
|
651
|
+
|
|
652
|
+
api_client.delete_manual_service_config(id=id)
|
|
653
|
+
|
|
654
|
+
result_dict = {
|
|
655
|
+
"success": True,
|
|
656
|
+
"message": f"Manual Service Confiuguration '{id}' has been successfully deleted"
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
debug_print(f"Successfully deleted manual service config perspective with ID: {id}")
|
|
660
|
+
return result_dict
|
|
661
|
+
|
|
662
|
+
except Exception as e:
|
|
663
|
+
debug_print(f"Error in delete_manual_service_config: {e}")
|
|
664
|
+
traceback.print_exc(file=sys.stderr)
|
|
665
|
+
return {"error": f"Failed to delete manual service configs: {e!s}"}
|
|
666
|
+
|
|
667
|
+
@register_as_tool
|
|
668
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
669
|
+
async def update_manual_service_config(
|
|
670
|
+
self,
|
|
671
|
+
id: str,
|
|
672
|
+
tagFilterExpression: Dict[str, Any],
|
|
673
|
+
unmonitoredServiceName: Optional[str] = None,
|
|
674
|
+
existingServiceId: Optional[str] = None,
|
|
675
|
+
description: Optional[str] = None,
|
|
676
|
+
enabled: Optional[bool] = True,
|
|
677
|
+
ctx=None,
|
|
678
|
+
api_client=None
|
|
679
|
+
) -> Dict[str, Any]:
|
|
680
|
+
"""
|
|
681
|
+
The manual service configuration APIs enables mapping calls to services using tag filter expressions based on call tags.
|
|
682
|
+
|
|
683
|
+
There are two use cases on the usage of these APIs:
|
|
684
|
+
|
|
685
|
+
Map to an Unmonitored Service with a Custom Name. For example, Map HTTP calls to different Google domains (www.ibm.com, www.ibm.fr) into a single service named IBM using the call.http.host tag.
|
|
686
|
+
Link Calls to an Existing Monitored Service. For example, Link database calls (jdbc:mysql://10.128.0.1:3306) to an existing service like MySQL@3306 on demo-host by referencing its service ID.
|
|
687
|
+
|
|
688
|
+
Args:
|
|
689
|
+
id: A unique id of the manual service configuration.
|
|
690
|
+
tagFilterExpression : Boolean expression of tag filters to match relevant calls.
|
|
691
|
+
unmonitoredServiceName : Custom name for an unmonitored service to map. (Optional)
|
|
692
|
+
existingServiceId : Service ID to link the matched calls to. (Optional)
|
|
693
|
+
description: Description of the mapping configuration. (Optional)
|
|
694
|
+
enabled: Enable or disable the configuration. Defaults to True. (Optional)
|
|
695
|
+
ctx: Optional execution context.
|
|
696
|
+
|
|
697
|
+
Returns:
|
|
698
|
+
Dict[str, Any]: API response indicating success or failure.
|
|
699
|
+
"""
|
|
700
|
+
try:
|
|
701
|
+
debug_print("Creating manual service configuration")
|
|
702
|
+
|
|
703
|
+
if not (unmonitoredServiceName and existingServiceId):
|
|
704
|
+
return {
|
|
705
|
+
"error": "You must provide either 'unmonitoredServiceName' or 'existingServiceId'."
|
|
706
|
+
}
|
|
707
|
+
if not id or not tagFilterExpression:
|
|
708
|
+
return {"error": "Required enitities are missing or invalid"}
|
|
709
|
+
|
|
710
|
+
body = {
|
|
711
|
+
"tagFilterExpression": tagFilterExpression,
|
|
712
|
+
"id": id
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
if unmonitoredServiceName:
|
|
716
|
+
body["unmonitoredServiceName"] = unmonitoredServiceName
|
|
717
|
+
if existingServiceId:
|
|
718
|
+
body["existingServiceId"] = existingServiceId
|
|
719
|
+
if description:
|
|
720
|
+
body["description"] = description
|
|
721
|
+
|
|
722
|
+
manual_service_config = ManualServiceConfig(**body)
|
|
723
|
+
|
|
724
|
+
result = api_client.update_manual_service_config(
|
|
725
|
+
id=id,
|
|
726
|
+
manual_service_config=manual_service_config
|
|
727
|
+
)
|
|
728
|
+
|
|
729
|
+
if hasattr(result, "to_dict"):
|
|
730
|
+
result_dict = result.to_dict()
|
|
731
|
+
else:
|
|
732
|
+
result_dict = result
|
|
733
|
+
|
|
734
|
+
debug_print(f"Manual service configuration result: {result_dict}")
|
|
735
|
+
return result_dict
|
|
736
|
+
|
|
737
|
+
except Exception as e:
|
|
738
|
+
debug_print(f"Error creating manual service configuration: {e}")
|
|
739
|
+
traceback.print_exc(file=sys.stderr)
|
|
740
|
+
return {"error": f"Failed to create manual service configuration: {e!s}"}
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
@register_as_tool
|
|
744
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
745
|
+
async def replace_all_manual_service_config(
|
|
746
|
+
self,
|
|
747
|
+
tagFilterExpression: Dict[str, Any],
|
|
748
|
+
unmonitoredServiceName: Optional[str] = None,
|
|
749
|
+
existingServiceId: Optional[str] = None,
|
|
750
|
+
description: Optional[str] = None,
|
|
751
|
+
enabled: Optional[bool] = True,
|
|
752
|
+
ctx=None,
|
|
753
|
+
api_client=None
|
|
754
|
+
) -> Dict[str, Any]:
|
|
755
|
+
"""
|
|
756
|
+
This tool is used if one wants to update more than 1 manual service configurations.
|
|
757
|
+
|
|
758
|
+
There are two use cases on the usage of these APIs:
|
|
759
|
+
|
|
760
|
+
Map to an Unmonitored Service with a Custom Name. For example, Map HTTP calls to different Google domains (www.ibm.com, www.ibm.fr) into a single service named IBM using the call.http.host tag.
|
|
761
|
+
Link Calls to an Existing Monitored Service. For example, Link database calls (jdbc:mysql://10.128.0.1:3306) to an existing service like MySQL@3306 on demo-host by referencing its service ID.
|
|
762
|
+
|
|
763
|
+
Args:
|
|
764
|
+
id: A unique id of the manual service configuration.
|
|
765
|
+
tagFilterExpression : Boolean expression of tag filters to match relevant calls.
|
|
766
|
+
unmonitoredServiceName : Custom name for an unmonitored service to map. (Optional)
|
|
767
|
+
existingServiceId : Service ID to link the matched calls to. (Optional)
|
|
768
|
+
description: Description of the mapping configuration. (Optional)
|
|
769
|
+
enabled: Enable or disable the configuration. Defaults to True. (Optional)
|
|
770
|
+
ctx: Optional execution context.
|
|
771
|
+
|
|
772
|
+
Returns:
|
|
773
|
+
Dict[str, Any]: API response indicating success or failure.
|
|
774
|
+
"""
|
|
775
|
+
try:
|
|
776
|
+
debug_print("Creating manual service configuration")
|
|
777
|
+
|
|
778
|
+
if not (unmonitoredServiceName and existingServiceId):
|
|
779
|
+
return {
|
|
780
|
+
"error": "You must provide either 'unmonitoredServiceName' or 'existingServiceId'."
|
|
781
|
+
}
|
|
782
|
+
if not tagFilterExpression:
|
|
783
|
+
return {"error": "Required enitities are missing or invalid"}
|
|
784
|
+
|
|
785
|
+
request_body = {}
|
|
786
|
+
|
|
787
|
+
if tagFilterExpression:
|
|
788
|
+
request_body["tagFilterExpression"] = {"tagFilterExpression": tagFilterExpression}
|
|
789
|
+
if unmonitoredServiceName:
|
|
790
|
+
request_body["unmonitoredServiceName"] = {"unmonitoredServiceName": unmonitoredServiceName}
|
|
791
|
+
if existingServiceId:
|
|
792
|
+
request_body["existingServiceId"] = {"existingServiceId": existingServiceId}
|
|
793
|
+
if description:
|
|
794
|
+
request_body["description"] = {"description": description}
|
|
795
|
+
|
|
796
|
+
new_manual_service_config = NewManualServiceConfig(**request_body)
|
|
797
|
+
|
|
798
|
+
result = api_client.replace_all_manual_service_configs(
|
|
799
|
+
new_manual_service_config=new_manual_service_config
|
|
800
|
+
)
|
|
801
|
+
|
|
802
|
+
if hasattr(result, "to_dict"):
|
|
803
|
+
result_dict = result.to_dict()
|
|
804
|
+
else:
|
|
805
|
+
result_dict = result
|
|
806
|
+
|
|
807
|
+
debug_print(f"Manual service configuration result: {result_dict}")
|
|
808
|
+
return result_dict
|
|
809
|
+
|
|
810
|
+
except Exception as e:
|
|
811
|
+
debug_print(f"Error creating manual service configuration: {e}")
|
|
812
|
+
traceback.print_exc(file=sys.stderr)
|
|
813
|
+
return {"error": f"Failed to create manual service configuration: {e!s}"}
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
@register_as_tool
|
|
817
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
818
|
+
async def get_all_service_configs(self,
|
|
819
|
+
ctx=None,
|
|
820
|
+
api_client=None) -> List[Dict[str, Any]]:
|
|
821
|
+
"""
|
|
822
|
+
This tool gives list of All Service Perspectives Configuration
|
|
823
|
+
Get a list of all Service Perspectives with their configuration settings.
|
|
824
|
+
Args:
|
|
825
|
+
ctx: The MCP context (optional)
|
|
826
|
+
|
|
827
|
+
Returns:
|
|
828
|
+
Dictionary containing endpoints data or error information
|
|
829
|
+
"""
|
|
830
|
+
try:
|
|
831
|
+
debug_print("Fetching all service configs")
|
|
832
|
+
result = api_client.get_service_configs()
|
|
833
|
+
# Convert the result to a dictionary
|
|
834
|
+
if hasattr(result, 'to_dict'):
|
|
835
|
+
result_dict = result.to_dict()
|
|
836
|
+
else:
|
|
837
|
+
# If it's already a dict or another format, use it as is
|
|
838
|
+
result_dict = result
|
|
839
|
+
|
|
840
|
+
debug_print(f"Result from get_service_configs: {result_dict}")
|
|
841
|
+
return result_dict
|
|
842
|
+
|
|
843
|
+
except Exception as e:
|
|
844
|
+
debug_print(f"Error in get_all_service_configs: {e}")
|
|
845
|
+
traceback.print_exc(file=sys.stderr)
|
|
846
|
+
return [{"error": f"Failed to get application data metrics: {e}"}]
|
|
847
|
+
|
|
848
|
+
@register_as_tool
|
|
849
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
850
|
+
async def add_service_configs(self,
|
|
851
|
+
enabled: bool,
|
|
852
|
+
match_specification: List[Dict[str, str]],
|
|
853
|
+
name: str,
|
|
854
|
+
label:str,
|
|
855
|
+
id: str,
|
|
856
|
+
comment: Optional[str] = None,
|
|
857
|
+
ctx=None,
|
|
858
|
+
api_client=None) -> List[Dict[str, Any]]:
|
|
859
|
+
"""
|
|
860
|
+
This tool gives is used to add new Service Perspectives Configuration
|
|
861
|
+
Get a list of all Service Perspectives with their configuration settings.
|
|
862
|
+
Args:
|
|
863
|
+
|
|
864
|
+
ctx: The MCP context (optional)
|
|
865
|
+
|
|
866
|
+
Returns:
|
|
867
|
+
Dictionary containing endpoints data or error information
|
|
868
|
+
"""
|
|
869
|
+
try:
|
|
870
|
+
debug_print("Adding new service config")
|
|
871
|
+
if not (enabled and match_specification and name and label and id):
|
|
872
|
+
return [{"error": "Required entities are missing or invalid"}]
|
|
873
|
+
|
|
874
|
+
body = {
|
|
875
|
+
"match_specification": match_specification,
|
|
876
|
+
"enabled": enabled,
|
|
877
|
+
"id": id,
|
|
878
|
+
"label": label,
|
|
879
|
+
"name": name
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
if comment:
|
|
883
|
+
body["comment"] = comment
|
|
884
|
+
|
|
885
|
+
service_config = ServiceConfig(**body)
|
|
886
|
+
|
|
887
|
+
result = api_client.add_service_config(
|
|
888
|
+
service_config=service_config
|
|
889
|
+
)
|
|
890
|
+
|
|
891
|
+
# Convert the result to a dictionary
|
|
892
|
+
if hasattr(result, 'to_dict'):
|
|
893
|
+
result_dict = result.to_dict()
|
|
894
|
+
else:
|
|
895
|
+
# If it's already a dict or another format, use it as is
|
|
896
|
+
result_dict = result
|
|
897
|
+
|
|
898
|
+
debug_print(f"Result from add_service_config: {result_dict}")
|
|
899
|
+
return result_dict
|
|
900
|
+
|
|
901
|
+
except Exception as e:
|
|
902
|
+
debug_print(f"Error in add_service_config: {e}")
|
|
903
|
+
traceback.print_exc(file=sys.stderr)
|
|
904
|
+
return [{"error": f"Failed to get application data metrics: {e}"}]
|
|
905
|
+
|
|
906
|
+
@register_as_tool
|
|
907
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
908
|
+
async def replace_all_service_configs(self,
|
|
909
|
+
enabled: bool,
|
|
910
|
+
match_specification: List[Dict[str, str]],
|
|
911
|
+
name: str,
|
|
912
|
+
label:str,
|
|
913
|
+
id: str,
|
|
914
|
+
comment: Optional[str] = None,
|
|
915
|
+
ctx=None,
|
|
916
|
+
api_client=None) -> List[Dict[str, Any]]:
|
|
917
|
+
"""
|
|
918
|
+
|
|
919
|
+
Args:
|
|
920
|
+
|
|
921
|
+
ctx: The MCP context (optional)
|
|
922
|
+
|
|
923
|
+
Returns:
|
|
924
|
+
Dictionary containing endpoints data or error information
|
|
925
|
+
"""
|
|
926
|
+
try:
|
|
927
|
+
debug_print("Fetching all service configs")
|
|
928
|
+
if not (enabled or match_specification or name or label or id):
|
|
929
|
+
return [{"error": "Required entities are missing or invalid"}]
|
|
930
|
+
|
|
931
|
+
body = {
|
|
932
|
+
"match_specification": match_specification,
|
|
933
|
+
"enabled": enabled,
|
|
934
|
+
"id": id,
|
|
935
|
+
"label": label,
|
|
936
|
+
"name": name
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
if comment:
|
|
940
|
+
body["comment"] = comment
|
|
941
|
+
|
|
942
|
+
service_config_list = [ServiceConfig(**body)]
|
|
943
|
+
|
|
944
|
+
result = api_client.replace_all(
|
|
945
|
+
service_config=service_config_list
|
|
946
|
+
)
|
|
947
|
+
|
|
948
|
+
# Convert the result to a dictionary
|
|
949
|
+
if hasattr(result, 'to_dict'):
|
|
950
|
+
result_dict = result.to_dict()
|
|
951
|
+
else:
|
|
952
|
+
# If it's already a dict or another format, use it as is
|
|
953
|
+
result_dict = result
|
|
954
|
+
|
|
955
|
+
debug_print(f"Result from get_service_configs: {result_dict}")
|
|
956
|
+
return result_dict
|
|
957
|
+
|
|
958
|
+
except Exception as e:
|
|
959
|
+
debug_print(f"Error in get_service_configs: {e}")
|
|
960
|
+
traceback.print_exc(file=sys.stderr)
|
|
961
|
+
return [{"error": f"Failed to get application data metrics: {e}"}]
|
|
962
|
+
@register_as_tool
|
|
963
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
964
|
+
async def order_service_config(self,
|
|
965
|
+
request_body: List[str],
|
|
966
|
+
ctx=None,
|
|
967
|
+
api_client=None) -> Dict[str, Any]:
|
|
968
|
+
"""
|
|
969
|
+
order Service Configurations (Custom Service Rules)
|
|
970
|
+
|
|
971
|
+
This tool changes the order of service configurations based on the provided list of IDs.
|
|
972
|
+
All service configuration IDs must be included in the request.
|
|
973
|
+
|
|
974
|
+
Args:
|
|
975
|
+
request_body: List of service configuration IDs in the desired order.
|
|
976
|
+
ctx: The MCP context (optional)
|
|
977
|
+
|
|
978
|
+
Returns:
|
|
979
|
+
A dictionary with the API response or error message.
|
|
980
|
+
"""
|
|
981
|
+
try:
|
|
982
|
+
debug_print("ordering service configurations")
|
|
983
|
+
|
|
984
|
+
if not request_body:
|
|
985
|
+
return {"error": "The list of service configuration IDs cannot be empty."}
|
|
986
|
+
|
|
987
|
+
result = api_client.order_service_config(
|
|
988
|
+
request_body=request_body
|
|
989
|
+
)
|
|
990
|
+
|
|
991
|
+
# Convert result to dict if needed
|
|
992
|
+
if hasattr(result, 'to_dict'):
|
|
993
|
+
return result.to_dict()
|
|
994
|
+
return result
|
|
995
|
+
|
|
996
|
+
except Exception as e:
|
|
997
|
+
debug_print(f"Error in order_service_config: {e}")
|
|
998
|
+
traceback.print_exc(file=sys.stderr)
|
|
999
|
+
return {"error": f"Failed to order service configs: {e!s}"}
|
|
1000
|
+
|
|
1001
|
+
@register_as_tool
|
|
1002
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
1003
|
+
async def delete_service_config(self,
|
|
1004
|
+
id: str,
|
|
1005
|
+
ctx=None,
|
|
1006
|
+
api_client=None) -> Dict[str, Any]:
|
|
1007
|
+
"""
|
|
1008
|
+
Delete a Service Perspective configuration.
|
|
1009
|
+
This tool allows you to delete an existing Service Config by its ID.
|
|
1010
|
+
|
|
1011
|
+
Args:
|
|
1012
|
+
id: The ID of the application perspective to delete
|
|
1013
|
+
ctx: The MCP context (optional)
|
|
1014
|
+
|
|
1015
|
+
Returns:
|
|
1016
|
+
Dictionary containing the result of the deletion or error information
|
|
1017
|
+
"""
|
|
1018
|
+
try:
|
|
1019
|
+
if not id:
|
|
1020
|
+
return {"error": "Service perspective ID is required for deletion"}
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
debug_print(f"Deleting application perspective with ID: {id}")
|
|
1024
|
+
# Call the delete_service_config method from the SDK
|
|
1025
|
+
api_client.delete_service_config(id=id)
|
|
1026
|
+
|
|
1027
|
+
result_dict = {
|
|
1028
|
+
"success": True,
|
|
1029
|
+
"message": f"Service Confiuguration '{id}' has been successfully deleted"
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
debug_print(f"Successfully deleted service perspective with ID: {id}")
|
|
1033
|
+
return result_dict
|
|
1034
|
+
except Exception as e:
|
|
1035
|
+
debug_print(f"Error in delete_service_config: {e}")
|
|
1036
|
+
traceback.print_exc(file=sys.stderr)
|
|
1037
|
+
return {"error": f"Failed to delete service configuration: {e!s}"}
|
|
1038
|
+
|
|
1039
|
+
@register_as_tool
|
|
1040
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
1041
|
+
async def get_service_config(
|
|
1042
|
+
self,
|
|
1043
|
+
id: str,
|
|
1044
|
+
ctx=None,
|
|
1045
|
+
api_client=None
|
|
1046
|
+
) -> Dict[str, Any]:
|
|
1047
|
+
"""
|
|
1048
|
+
This MCP tool is used if one wants to retrieve the particular custom service configuration.
|
|
1049
|
+
Args:
|
|
1050
|
+
id: An Instana generated unique identifier for a Service.
|
|
1051
|
+
ctx: The MCP context (optional)
|
|
1052
|
+
|
|
1053
|
+
Returns:
|
|
1054
|
+
Dict[str, Any]: Response from the create/update endpoint configuration API.
|
|
1055
|
+
|
|
1056
|
+
"""
|
|
1057
|
+
try:
|
|
1058
|
+
debug_print("get service config")
|
|
1059
|
+
if not id:
|
|
1060
|
+
return {"error": "Required entities are missing or invalid"}
|
|
1061
|
+
|
|
1062
|
+
result = api_client.get_service_config(
|
|
1063
|
+
id=id
|
|
1064
|
+
)
|
|
1065
|
+
# Convert the result to a dictionary
|
|
1066
|
+
if hasattr(result, 'to_dict'):
|
|
1067
|
+
result_dict = result.to_dict()
|
|
1068
|
+
else:
|
|
1069
|
+
# If it's already a dict or another format, use it as is
|
|
1070
|
+
result_dict = result
|
|
1071
|
+
|
|
1072
|
+
debug_print(f"Result from get_service_config: {result_dict}")
|
|
1073
|
+
return result_dict
|
|
1074
|
+
except Exception as e:
|
|
1075
|
+
debug_print(f"Error in get_service_config: {e}")
|
|
1076
|
+
traceback.print_exc(file=sys.stderr)
|
|
1077
|
+
return {"error": f"Failed to get service config: {e!s}"}
|
|
1078
|
+
|
|
1079
|
+
@register_as_tool
|
|
1080
|
+
@with_header_auth(ApplicationSettingsApi)
|
|
1081
|
+
async def update_service_configs(self,
|
|
1082
|
+
enabled: bool,
|
|
1083
|
+
match_specification: List[Dict[str, str]],
|
|
1084
|
+
name: str,
|
|
1085
|
+
label:str,
|
|
1086
|
+
id: str,
|
|
1087
|
+
comment: Optional[str] = None,
|
|
1088
|
+
ctx=None,
|
|
1089
|
+
api_client=None) -> List[Dict[str, Any]]:
|
|
1090
|
+
"""
|
|
1091
|
+
This tool gives is used if one wants to update a particular custom service rule.
|
|
1092
|
+
Args:
|
|
1093
|
+
|
|
1094
|
+
ctx: The MCP context (optional)
|
|
1095
|
+
|
|
1096
|
+
Returns:
|
|
1097
|
+
Dictionary containing endpoints data or error information
|
|
1098
|
+
"""
|
|
1099
|
+
try:
|
|
1100
|
+
debug_print("Adding new service config")
|
|
1101
|
+
if not (id and name and label and isinstance(match_specification, list)):
|
|
1102
|
+
return [{"error": "Required entities are missing or invalid"}]
|
|
1103
|
+
|
|
1104
|
+
body = {
|
|
1105
|
+
"match_specification": match_specification,
|
|
1106
|
+
"enabled": enabled,
|
|
1107
|
+
"id": id,
|
|
1108
|
+
"label": label,
|
|
1109
|
+
"name": name
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
if comment:
|
|
1113
|
+
body["comment"] = comment
|
|
1114
|
+
|
|
1115
|
+
service_config = ServiceConfig(**body)
|
|
1116
|
+
|
|
1117
|
+
result = api_client.put_service_config(
|
|
1118
|
+
id=id,
|
|
1119
|
+
service_config=service_config
|
|
1120
|
+
)
|
|
1121
|
+
|
|
1122
|
+
# Convert the result to a dictionary
|
|
1123
|
+
if hasattr(result, 'to_dict'):
|
|
1124
|
+
result_dict = result.to_dict()
|
|
1125
|
+
else:
|
|
1126
|
+
# If it's already a dict or another format, use it as is
|
|
1127
|
+
result_dict = result
|
|
1128
|
+
|
|
1129
|
+
debug_print(f"Result from add_service_config: {result_dict}")
|
|
1130
|
+
return result_dict
|
|
1131
|
+
|
|
1132
|
+
except Exception as e:
|
|
1133
|
+
debug_print(f"Error in add_service_config: {e}")
|
|
1134
|
+
traceback.print_exc(file=sys.stderr)
|
|
1135
|
+
return [{"error": f"Failed to add new service config: {e!s}"}]
|