kailash 0.8.4__py3-none-any.whl → 0.8.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.
Files changed (79) hide show
  1. kailash/__init__.py +1 -7
  2. kailash/cli/__init__.py +11 -1
  3. kailash/cli/validation_audit.py +570 -0
  4. kailash/core/actors/supervisor.py +1 -1
  5. kailash/core/resilience/circuit_breaker.py +71 -1
  6. kailash/core/resilience/health_monitor.py +172 -0
  7. kailash/edge/compliance.py +33 -0
  8. kailash/edge/consistency.py +609 -0
  9. kailash/edge/coordination/__init__.py +30 -0
  10. kailash/edge/coordination/global_ordering.py +355 -0
  11. kailash/edge/coordination/leader_election.py +217 -0
  12. kailash/edge/coordination/partition_detector.py +296 -0
  13. kailash/edge/coordination/raft.py +485 -0
  14. kailash/edge/discovery.py +63 -1
  15. kailash/edge/migration/__init__.py +19 -0
  16. kailash/edge/migration/edge_migrator.py +832 -0
  17. kailash/edge/monitoring/__init__.py +21 -0
  18. kailash/edge/monitoring/edge_monitor.py +736 -0
  19. kailash/edge/prediction/__init__.py +10 -0
  20. kailash/edge/prediction/predictive_warmer.py +591 -0
  21. kailash/edge/resource/__init__.py +102 -0
  22. kailash/edge/resource/cloud_integration.py +796 -0
  23. kailash/edge/resource/cost_optimizer.py +949 -0
  24. kailash/edge/resource/docker_integration.py +919 -0
  25. kailash/edge/resource/kubernetes_integration.py +893 -0
  26. kailash/edge/resource/platform_integration.py +913 -0
  27. kailash/edge/resource/predictive_scaler.py +959 -0
  28. kailash/edge/resource/resource_analyzer.py +824 -0
  29. kailash/edge/resource/resource_pools.py +610 -0
  30. kailash/integrations/dataflow_edge.py +261 -0
  31. kailash/mcp_server/registry_integration.py +1 -1
  32. kailash/monitoring/__init__.py +18 -0
  33. kailash/monitoring/alerts.py +646 -0
  34. kailash/monitoring/metrics.py +677 -0
  35. kailash/nodes/__init__.py +2 -0
  36. kailash/nodes/ai/semantic_memory.py +2 -2
  37. kailash/nodes/base.py +545 -0
  38. kailash/nodes/edge/__init__.py +36 -0
  39. kailash/nodes/edge/base.py +240 -0
  40. kailash/nodes/edge/cloud_node.py +710 -0
  41. kailash/nodes/edge/coordination.py +239 -0
  42. kailash/nodes/edge/docker_node.py +825 -0
  43. kailash/nodes/edge/edge_data.py +582 -0
  44. kailash/nodes/edge/edge_migration_node.py +392 -0
  45. kailash/nodes/edge/edge_monitoring_node.py +421 -0
  46. kailash/nodes/edge/edge_state.py +673 -0
  47. kailash/nodes/edge/edge_warming_node.py +393 -0
  48. kailash/nodes/edge/kubernetes_node.py +652 -0
  49. kailash/nodes/edge/platform_node.py +766 -0
  50. kailash/nodes/edge/resource_analyzer_node.py +378 -0
  51. kailash/nodes/edge/resource_optimizer_node.py +501 -0
  52. kailash/nodes/edge/resource_scaler_node.py +397 -0
  53. kailash/nodes/ports.py +676 -0
  54. kailash/runtime/local.py +344 -1
  55. kailash/runtime/validation/__init__.py +20 -0
  56. kailash/runtime/validation/connection_context.py +119 -0
  57. kailash/runtime/validation/enhanced_error_formatter.py +202 -0
  58. kailash/runtime/validation/error_categorizer.py +164 -0
  59. kailash/runtime/validation/metrics.py +380 -0
  60. kailash/runtime/validation/performance.py +615 -0
  61. kailash/runtime/validation/suggestion_engine.py +212 -0
  62. kailash/testing/fixtures.py +2 -2
  63. kailash/workflow/builder.py +230 -4
  64. kailash/workflow/contracts.py +418 -0
  65. kailash/workflow/edge_infrastructure.py +369 -0
  66. kailash/workflow/migration.py +3 -3
  67. kailash/workflow/type_inference.py +669 -0
  68. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/METADATA +43 -27
  69. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/RECORD +73 -27
  70. kailash/nexus/__init__.py +0 -21
  71. kailash/nexus/cli/__init__.py +0 -5
  72. kailash/nexus/cli/__main__.py +0 -6
  73. kailash/nexus/cli/main.py +0 -176
  74. kailash/nexus/factory.py +0 -413
  75. kailash/nexus/gateway.py +0 -545
  76. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/WHEEL +0 -0
  77. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/entry_points.txt +0 -0
  78. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/licenses/LICENSE +0 -0
  79. {kailash-0.8.4.dist-info → kailash-0.8.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,710 @@
1
+ """Cloud integration node for edge resource management."""
2
+
3
+ from datetime import datetime, timedelta
4
+ from typing import Any, Dict, List, Optional
5
+
6
+ from kailash.edge.resource.cloud_integration import (
7
+ CloudIntegration,
8
+ CloudProvider,
9
+ InstanceSpec,
10
+ InstanceState,
11
+ InstanceType,
12
+ )
13
+ from kailash.nodes.base import NodeParameter, register_node
14
+ from kailash.nodes.base_async import AsyncNode
15
+
16
+
17
+ @register_node()
18
+ class CloudNode(AsyncNode):
19
+ """Node for cloud resource management and integration."""
20
+
21
+ def __init__(self, **kwargs):
22
+ super().__init__(**kwargs)
23
+ self.cloud_integration: Optional[CloudIntegration] = None
24
+
25
+ @property
26
+ def input_parameters(self) -> Dict[str, NodeParameter]:
27
+ """Define input parameters."""
28
+ return {
29
+ "operation": NodeParameter(
30
+ name="operation",
31
+ type=str,
32
+ required=True,
33
+ description="Operation to perform",
34
+ enum=[
35
+ "initialize",
36
+ "register_aws",
37
+ "register_gcp",
38
+ "register_azure",
39
+ "create_instance",
40
+ "get_instance_status",
41
+ "terminate_instance",
42
+ "list_instances",
43
+ "get_instance_metrics",
44
+ "get_supported_providers",
45
+ "get_provider_info",
46
+ "start_monitoring",
47
+ "stop_monitoring",
48
+ ],
49
+ ),
50
+ # Provider registration
51
+ "provider": NodeParameter(
52
+ name="provider",
53
+ type=str,
54
+ required=False,
55
+ description="Cloud provider",
56
+ enum=["aws", "gcp", "azure", "alibaba_cloud", "digital_ocean"],
57
+ ),
58
+ "region": NodeParameter(
59
+ name="region", type=str, required=False, description="Cloud region"
60
+ ),
61
+ "zone": NodeParameter(
62
+ name="zone",
63
+ type=str,
64
+ required=False,
65
+ description="Cloud availability zone",
66
+ ),
67
+ "profile_name": NodeParameter(
68
+ name="profile_name",
69
+ type=str,
70
+ required=False,
71
+ description="AWS profile name",
72
+ ),
73
+ "project_id": NodeParameter(
74
+ name="project_id",
75
+ type=str,
76
+ required=False,
77
+ description="GCP project ID",
78
+ ),
79
+ "credentials_path": NodeParameter(
80
+ name="credentials_path",
81
+ type=str,
82
+ required=False,
83
+ description="Path to credentials file",
84
+ ),
85
+ "subscription_id": NodeParameter(
86
+ name="subscription_id",
87
+ type=str,
88
+ required=False,
89
+ description="Azure subscription ID",
90
+ ),
91
+ "resource_group": NodeParameter(
92
+ name="resource_group",
93
+ type=str,
94
+ required=False,
95
+ description="Azure resource group",
96
+ ),
97
+ # Instance operations
98
+ "instance_name": NodeParameter(
99
+ name="instance_name",
100
+ type=str,
101
+ required=False,
102
+ description="Instance name",
103
+ ),
104
+ "instance_id": NodeParameter(
105
+ name="instance_id", type=str, required=False, description="Instance ID"
106
+ ),
107
+ "instance_type": NodeParameter(
108
+ name="instance_type",
109
+ type=str,
110
+ required=False,
111
+ description="Instance type/size",
112
+ ),
113
+ "image_id": NodeParameter(
114
+ name="image_id",
115
+ type=str,
116
+ required=False,
117
+ description="Machine image ID",
118
+ ),
119
+ "subnet_id": NodeParameter(
120
+ name="subnet_id", type=str, required=False, description="Subnet ID"
121
+ ),
122
+ "security_group_ids": NodeParameter(
123
+ name="security_group_ids",
124
+ type=list,
125
+ required=False,
126
+ description="Security group IDs",
127
+ ),
128
+ "key_name": NodeParameter(
129
+ name="key_name", type=str, required=False, description="SSH key name"
130
+ ),
131
+ "user_data": NodeParameter(
132
+ name="user_data",
133
+ type=str,
134
+ required=False,
135
+ description="Instance user data script",
136
+ ),
137
+ "tags": NodeParameter(
138
+ name="tags", type=dict, required=False, description="Instance tags"
139
+ ),
140
+ "edge_node": NodeParameter(
141
+ name="edge_node",
142
+ type=str,
143
+ required=False,
144
+ description="Target edge node for instance placement",
145
+ ),
146
+ "min_count": NodeParameter(
147
+ name="min_count",
148
+ type=int,
149
+ required=False,
150
+ description="Minimum instance count",
151
+ ),
152
+ "max_count": NodeParameter(
153
+ name="max_count",
154
+ type=int,
155
+ required=False,
156
+ description="Maximum instance count",
157
+ ),
158
+ # List and filter operations
159
+ "filters": NodeParameter(
160
+ name="filters",
161
+ type=dict,
162
+ required=False,
163
+ description="Instance filters",
164
+ ),
165
+ # Metrics operations
166
+ "start_time": NodeParameter(
167
+ name="start_time",
168
+ type=str,
169
+ required=False,
170
+ description="Metrics start time (ISO format)",
171
+ ),
172
+ "end_time": NodeParameter(
173
+ name="end_time",
174
+ type=str,
175
+ required=False,
176
+ description="Metrics end time (ISO format)",
177
+ ),
178
+ "metrics_hours": NodeParameter(
179
+ name="metrics_hours",
180
+ type=int,
181
+ required=False,
182
+ description="Hours of metrics to retrieve (from now)",
183
+ ),
184
+ }
185
+
186
+ @property
187
+ def output_parameters(self) -> Dict[str, NodeParameter]:
188
+ """Define output parameters."""
189
+ return {
190
+ "status": NodeParameter(
191
+ name="status", type=str, description="Operation status"
192
+ ),
193
+ "result": NodeParameter(
194
+ name="result", type=dict, description="Operation result"
195
+ ),
196
+ "instances": NodeParameter(
197
+ name="instances", type=list, description="List of instances"
198
+ ),
199
+ "metrics": NodeParameter(
200
+ name="metrics", type=list, description="Instance metrics"
201
+ ),
202
+ "providers": NodeParameter(
203
+ name="providers", type=list, description="Supported cloud providers"
204
+ ),
205
+ "provider_info": NodeParameter(
206
+ name="provider_info",
207
+ type=dict,
208
+ description="Cloud provider information",
209
+ ),
210
+ "cloud_initialized": NodeParameter(
211
+ name="cloud_initialized",
212
+ type=bool,
213
+ description="Whether cloud integration was initialized",
214
+ ),
215
+ "provider_registered": NodeParameter(
216
+ name="provider_registered",
217
+ type=bool,
218
+ description="Whether cloud provider was registered",
219
+ ),
220
+ "instance_created": NodeParameter(
221
+ name="instance_created",
222
+ type=bool,
223
+ description="Whether instance was created",
224
+ ),
225
+ "instance_terminated": NodeParameter(
226
+ name="instance_terminated",
227
+ type=bool,
228
+ description="Whether instance was terminated",
229
+ ),
230
+ "monitoring_started": NodeParameter(
231
+ name="monitoring_started",
232
+ type=bool,
233
+ description="Whether monitoring was started",
234
+ ),
235
+ "monitoring_stopped": NodeParameter(
236
+ name="monitoring_stopped",
237
+ type=bool,
238
+ description="Whether monitoring was stopped",
239
+ ),
240
+ }
241
+
242
+ def get_parameters(self) -> Dict[str, NodeParameter]:
243
+ """Get all parameters for this node."""
244
+ return self.input_parameters
245
+
246
+ async def async_run(self, **kwargs) -> Dict[str, Any]:
247
+ """Execute cloud operation.
248
+
249
+ Args:
250
+ **kwargs: Operation parameters
251
+
252
+ Returns:
253
+ Operation result
254
+ """
255
+ operation = kwargs.get("operation")
256
+
257
+ if not operation:
258
+ return {"status": "error", "error": "Operation is required"}
259
+
260
+ try:
261
+ if operation == "initialize":
262
+ return await self._initialize_cloud(**kwargs)
263
+ elif operation == "register_aws":
264
+ return await self._register_aws(**kwargs)
265
+ elif operation == "register_gcp":
266
+ return await self._register_gcp(**kwargs)
267
+ elif operation == "register_azure":
268
+ return await self._register_azure(**kwargs)
269
+ elif operation == "create_instance":
270
+ return await self._create_instance(**kwargs)
271
+ elif operation == "get_instance_status":
272
+ return await self._get_instance_status(**kwargs)
273
+ elif operation == "terminate_instance":
274
+ return await self._terminate_instance(**kwargs)
275
+ elif operation == "list_instances":
276
+ return await self._list_instances(**kwargs)
277
+ elif operation == "get_instance_metrics":
278
+ return await self._get_instance_metrics(**kwargs)
279
+ elif operation == "get_supported_providers":
280
+ return await self._get_supported_providers(**kwargs)
281
+ elif operation == "get_provider_info":
282
+ return await self._get_provider_info(**kwargs)
283
+ elif operation == "start_monitoring":
284
+ return await self._start_monitoring(**kwargs)
285
+ elif operation == "stop_monitoring":
286
+ return await self._stop_monitoring(**kwargs)
287
+ else:
288
+ return {"status": "error", "error": f"Unknown operation: {operation}"}
289
+
290
+ except Exception as e:
291
+ return {"status": "error", "error": f"Cloud operation failed: {str(e)}"}
292
+
293
+ async def _initialize_cloud(self, **kwargs) -> Dict[str, Any]:
294
+ """Initialize cloud integration."""
295
+ try:
296
+ self.cloud_integration = CloudIntegration()
297
+
298
+ return {
299
+ "status": "success",
300
+ "cloud_initialized": True,
301
+ "result": {"message": "Cloud integration initialized successfully"},
302
+ }
303
+
304
+ except Exception as e:
305
+ return {
306
+ "status": "error",
307
+ "cloud_initialized": False,
308
+ "error": f"Failed to initialize cloud integration: {str(e)}",
309
+ }
310
+
311
+ async def _register_aws(self, **kwargs) -> Dict[str, Any]:
312
+ """Register AWS provider."""
313
+ if not self.cloud_integration:
314
+ await self._initialize_cloud(**kwargs)
315
+
316
+ region = kwargs.get("region", "us-west-2")
317
+ profile_name = kwargs.get("profile_name")
318
+
319
+ try:
320
+ self.cloud_integration.register_aws(region, profile_name)
321
+
322
+ return {
323
+ "status": "success",
324
+ "provider_registered": True,
325
+ "result": {
326
+ "provider": "aws",
327
+ "region": region,
328
+ "profile_name": profile_name,
329
+ "message": "AWS provider registered successfully",
330
+ },
331
+ }
332
+
333
+ except Exception as e:
334
+ return {
335
+ "status": "error",
336
+ "provider_registered": False,
337
+ "error": f"Failed to register AWS provider: {str(e)}",
338
+ }
339
+
340
+ async def _register_gcp(self, **kwargs) -> Dict[str, Any]:
341
+ """Register GCP provider."""
342
+ if not self.cloud_integration:
343
+ await self._initialize_cloud(**kwargs)
344
+
345
+ project_id = kwargs.get("project_id")
346
+ zone = kwargs.get("zone", "us-central1-a")
347
+ credentials_path = kwargs.get("credentials_path")
348
+
349
+ if not project_id:
350
+ return {
351
+ "status": "error",
352
+ "provider_registered": False,
353
+ "error": "project_id is required for GCP registration",
354
+ }
355
+
356
+ try:
357
+ self.cloud_integration.register_gcp(project_id, zone, credentials_path)
358
+
359
+ return {
360
+ "status": "success",
361
+ "provider_registered": True,
362
+ "result": {
363
+ "provider": "gcp",
364
+ "project_id": project_id,
365
+ "zone": zone,
366
+ "credentials_path": credentials_path,
367
+ "message": "GCP provider registered successfully",
368
+ },
369
+ }
370
+
371
+ except Exception as e:
372
+ return {
373
+ "status": "error",
374
+ "provider_registered": False,
375
+ "error": f"Failed to register GCP provider: {str(e)}",
376
+ }
377
+
378
+ async def _register_azure(self, **kwargs) -> Dict[str, Any]:
379
+ """Register Azure provider."""
380
+ if not self.cloud_integration:
381
+ await self._initialize_cloud(**kwargs)
382
+
383
+ subscription_id = kwargs.get("subscription_id")
384
+ resource_group = kwargs.get("resource_group")
385
+
386
+ if not subscription_id or not resource_group:
387
+ return {
388
+ "status": "error",
389
+ "provider_registered": False,
390
+ "error": "subscription_id and resource_group are required for Azure registration",
391
+ }
392
+
393
+ try:
394
+ self.cloud_integration.register_azure(subscription_id, resource_group)
395
+
396
+ return {
397
+ "status": "success",
398
+ "provider_registered": True,
399
+ "result": {
400
+ "provider": "azure",
401
+ "subscription_id": subscription_id,
402
+ "resource_group": resource_group,
403
+ "message": "Azure provider registered successfully",
404
+ },
405
+ }
406
+
407
+ except Exception as e:
408
+ return {
409
+ "status": "error",
410
+ "provider_registered": False,
411
+ "error": f"Failed to register Azure provider: {str(e)}",
412
+ }
413
+
414
+ async def _create_instance(self, **kwargs) -> Dict[str, Any]:
415
+ """Create cloud instance."""
416
+ if not self.cloud_integration:
417
+ await self._initialize_cloud(**kwargs)
418
+
419
+ provider = kwargs.get("provider")
420
+ instance_name = kwargs.get("instance_name")
421
+ instance_type = kwargs.get("instance_type")
422
+ image_id = kwargs.get("image_id")
423
+ region = kwargs.get("region")
424
+
425
+ if not all([provider, instance_name, instance_type, image_id, region]):
426
+ return {
427
+ "status": "error",
428
+ "instance_created": False,
429
+ "error": "provider, instance_name, instance_type, image_id, and region are required",
430
+ }
431
+
432
+ try:
433
+ # Create instance specification
434
+ spec = InstanceSpec(
435
+ name=instance_name,
436
+ provider=CloudProvider(provider),
437
+ instance_type=instance_type,
438
+ image_id=image_id,
439
+ region=region,
440
+ zone=kwargs.get("zone"),
441
+ subnet_id=kwargs.get("subnet_id"),
442
+ security_group_ids=kwargs.get("security_group_ids", []),
443
+ key_name=kwargs.get("key_name"),
444
+ user_data=kwargs.get("user_data"),
445
+ tags=kwargs.get("tags", {}),
446
+ edge_node=kwargs.get("edge_node"),
447
+ min_count=kwargs.get("min_count", 1),
448
+ max_count=kwargs.get("max_count", 1),
449
+ )
450
+
451
+ # Create instance
452
+ result = await self.cloud_integration.create_instance(spec)
453
+
454
+ return {
455
+ "status": result.get("status", "unknown"),
456
+ "instance_created": result.get("status") == "created",
457
+ "result": result,
458
+ }
459
+
460
+ except Exception as e:
461
+ return {
462
+ "status": "error",
463
+ "instance_created": False,
464
+ "error": f"Failed to create instance: {str(e)}",
465
+ }
466
+
467
+ async def _get_instance_status(self, **kwargs) -> Dict[str, Any]:
468
+ """Get cloud instance status."""
469
+ if not self.cloud_integration:
470
+ await self._initialize_cloud(**kwargs)
471
+
472
+ provider = kwargs.get("provider")
473
+ instance_id = kwargs.get("instance_id") or kwargs.get("instance_name")
474
+
475
+ if not provider or not instance_id:
476
+ return {
477
+ "status": "error",
478
+ "error": "provider and instance_id (or instance_name) are required",
479
+ }
480
+
481
+ try:
482
+ status = await self.cloud_integration.get_instance_status(
483
+ CloudProvider(provider), instance_id, kwargs.get("zone")
484
+ )
485
+
486
+ return {"status": "success", "result": status}
487
+
488
+ except Exception as e:
489
+ return {
490
+ "status": "error",
491
+ "error": f"Failed to get instance status: {str(e)}",
492
+ }
493
+
494
+ async def _terminate_instance(self, **kwargs) -> Dict[str, Any]:
495
+ """Terminate cloud instance."""
496
+ if not self.cloud_integration:
497
+ await self._initialize_cloud(**kwargs)
498
+
499
+ provider = kwargs.get("provider")
500
+ instance_id = kwargs.get("instance_id") or kwargs.get("instance_name")
501
+
502
+ if not provider or not instance_id:
503
+ return {
504
+ "status": "error",
505
+ "instance_terminated": False,
506
+ "error": "provider and instance_id (or instance_name) are required",
507
+ }
508
+
509
+ try:
510
+ result = await self.cloud_integration.terminate_instance(
511
+ CloudProvider(provider), instance_id, kwargs.get("zone")
512
+ )
513
+
514
+ return {
515
+ "status": result.get("status", "unknown"),
516
+ "instance_terminated": result.get("status")
517
+ in ["terminating", "deleting"],
518
+ "result": result,
519
+ }
520
+
521
+ except Exception as e:
522
+ return {
523
+ "status": "error",
524
+ "instance_terminated": False,
525
+ "error": f"Failed to terminate instance: {str(e)}",
526
+ }
527
+
528
+ async def _list_instances(self, **kwargs) -> Dict[str, Any]:
529
+ """List cloud instances."""
530
+ if not self.cloud_integration:
531
+ await self._initialize_cloud(**kwargs)
532
+
533
+ provider = kwargs.get("provider")
534
+ filters = kwargs.get("filters")
535
+
536
+ if not provider:
537
+ return {"status": "error", "instances": [], "error": "provider is required"}
538
+
539
+ try:
540
+ instances = await self.cloud_integration.list_instances(
541
+ CloudProvider(provider), filters
542
+ )
543
+
544
+ return {
545
+ "status": "success",
546
+ "instances": instances,
547
+ "result": {"instance_count": len(instances), "instances": instances},
548
+ }
549
+
550
+ except Exception as e:
551
+ return {
552
+ "status": "error",
553
+ "instances": [],
554
+ "error": f"Failed to list instances: {str(e)}",
555
+ }
556
+
557
+ async def _get_instance_metrics(self, **kwargs) -> Dict[str, Any]:
558
+ """Get cloud instance metrics."""
559
+ if not self.cloud_integration:
560
+ await self._initialize_cloud(**kwargs)
561
+
562
+ provider = kwargs.get("provider")
563
+ instance_id = kwargs.get("instance_id") or kwargs.get("instance_name")
564
+
565
+ if not provider or not instance_id:
566
+ return {
567
+ "status": "error",
568
+ "metrics": [],
569
+ "error": "provider and instance_id (or instance_name) are required",
570
+ }
571
+
572
+ try:
573
+ # Determine time range
574
+ if kwargs.get("start_time") and kwargs.get("end_time"):
575
+ start_time = datetime.fromisoformat(
576
+ kwargs["start_time"].replace("Z", "+00:00")
577
+ )
578
+ end_time = datetime.fromisoformat(
579
+ kwargs["end_time"].replace("Z", "+00:00")
580
+ )
581
+ else:
582
+ hours = kwargs.get("metrics_hours", 1)
583
+ end_time = datetime.now()
584
+ start_time = end_time - timedelta(hours=hours)
585
+
586
+ metrics = await self.cloud_integration.get_instance_metrics(
587
+ CloudProvider(provider), instance_id, start_time, end_time
588
+ )
589
+
590
+ metrics_data = [metric.to_dict() for metric in metrics]
591
+
592
+ return {
593
+ "status": "success",
594
+ "metrics": metrics_data,
595
+ "result": {
596
+ "metric_count": len(metrics_data),
597
+ "metrics": metrics_data,
598
+ "start_time": start_time.isoformat(),
599
+ "end_time": end_time.isoformat(),
600
+ },
601
+ }
602
+
603
+ except Exception as e:
604
+ return {
605
+ "status": "error",
606
+ "metrics": [],
607
+ "error": f"Failed to get instance metrics: {str(e)}",
608
+ }
609
+
610
+ async def _get_supported_providers(self, **kwargs) -> Dict[str, Any]:
611
+ """Get supported cloud providers."""
612
+ if not self.cloud_integration:
613
+ await self._initialize_cloud(**kwargs)
614
+
615
+ try:
616
+ providers = await self.cloud_integration.get_supported_providers()
617
+
618
+ return {
619
+ "status": "success",
620
+ "providers": providers,
621
+ "result": {"provider_count": len(providers), "providers": providers},
622
+ }
623
+
624
+ except Exception as e:
625
+ return {
626
+ "status": "error",
627
+ "providers": [],
628
+ "error": f"Failed to get supported providers: {str(e)}",
629
+ }
630
+
631
+ async def _get_provider_info(self, **kwargs) -> Dict[str, Any]:
632
+ """Get cloud provider information."""
633
+ if not self.cloud_integration:
634
+ await self._initialize_cloud(**kwargs)
635
+
636
+ provider = kwargs.get("provider")
637
+
638
+ if not provider:
639
+ return {
640
+ "status": "error",
641
+ "provider_info": {},
642
+ "error": "provider is required",
643
+ }
644
+
645
+ try:
646
+ provider_info = await self.cloud_integration.get_provider_info(
647
+ CloudProvider(provider)
648
+ )
649
+
650
+ return {
651
+ "status": "success",
652
+ "provider_info": provider_info,
653
+ "result": provider_info,
654
+ }
655
+
656
+ except Exception as e:
657
+ return {
658
+ "status": "error",
659
+ "provider_info": {},
660
+ "error": f"Failed to get provider info: {str(e)}",
661
+ }
662
+
663
+ async def _start_monitoring(self, **kwargs) -> Dict[str, Any]:
664
+ """Start cloud monitoring."""
665
+ if not self.cloud_integration:
666
+ await self._initialize_cloud(**kwargs)
667
+
668
+ try:
669
+ await self.cloud_integration.start_monitoring()
670
+
671
+ return {
672
+ "status": "success",
673
+ "monitoring_started": True,
674
+ "result": {
675
+ "message": "Cloud monitoring started",
676
+ "monitoring_interval": self.cloud_integration.monitoring_interval,
677
+ },
678
+ }
679
+
680
+ except Exception as e:
681
+ return {
682
+ "status": "error",
683
+ "monitoring_started": False,
684
+ "error": f"Failed to start monitoring: {str(e)}",
685
+ }
686
+
687
+ async def _stop_monitoring(self, **kwargs) -> Dict[str, Any]:
688
+ """Stop cloud monitoring."""
689
+ if not self.cloud_integration:
690
+ return {
691
+ "status": "error",
692
+ "monitoring_stopped": False,
693
+ "error": "Cloud integration not initialized",
694
+ }
695
+
696
+ try:
697
+ await self.cloud_integration.stop_monitoring()
698
+
699
+ return {
700
+ "status": "success",
701
+ "monitoring_stopped": True,
702
+ "result": {"message": "Cloud monitoring stopped"},
703
+ }
704
+
705
+ except Exception as e:
706
+ return {
707
+ "status": "error",
708
+ "monitoring_stopped": False,
709
+ "error": f"Failed to stop monitoring: {str(e)}",
710
+ }