kubectl-mcp-server 1.12.0__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 (45) hide show
  1. kubectl_mcp_server-1.12.0.dist-info/METADATA +711 -0
  2. kubectl_mcp_server-1.12.0.dist-info/RECORD +45 -0
  3. kubectl_mcp_server-1.12.0.dist-info/WHEEL +5 -0
  4. kubectl_mcp_server-1.12.0.dist-info/entry_points.txt +3 -0
  5. kubectl_mcp_server-1.12.0.dist-info/licenses/LICENSE +21 -0
  6. kubectl_mcp_server-1.12.0.dist-info/top_level.txt +2 -0
  7. kubectl_mcp_tool/__init__.py +21 -0
  8. kubectl_mcp_tool/__main__.py +46 -0
  9. kubectl_mcp_tool/auth/__init__.py +13 -0
  10. kubectl_mcp_tool/auth/config.py +71 -0
  11. kubectl_mcp_tool/auth/scopes.py +148 -0
  12. kubectl_mcp_tool/auth/verifier.py +82 -0
  13. kubectl_mcp_tool/cli/__init__.py +9 -0
  14. kubectl_mcp_tool/cli/__main__.py +10 -0
  15. kubectl_mcp_tool/cli/cli.py +111 -0
  16. kubectl_mcp_tool/diagnostics.py +355 -0
  17. kubectl_mcp_tool/k8s_config.py +289 -0
  18. kubectl_mcp_tool/mcp_server.py +530 -0
  19. kubectl_mcp_tool/prompts/__init__.py +5 -0
  20. kubectl_mcp_tool/prompts/prompts.py +823 -0
  21. kubectl_mcp_tool/resources/__init__.py +5 -0
  22. kubectl_mcp_tool/resources/resources.py +305 -0
  23. kubectl_mcp_tool/tools/__init__.py +28 -0
  24. kubectl_mcp_tool/tools/browser.py +371 -0
  25. kubectl_mcp_tool/tools/cluster.py +315 -0
  26. kubectl_mcp_tool/tools/core.py +421 -0
  27. kubectl_mcp_tool/tools/cost.py +680 -0
  28. kubectl_mcp_tool/tools/deployments.py +381 -0
  29. kubectl_mcp_tool/tools/diagnostics.py +174 -0
  30. kubectl_mcp_tool/tools/helm.py +1561 -0
  31. kubectl_mcp_tool/tools/networking.py +296 -0
  32. kubectl_mcp_tool/tools/operations.py +501 -0
  33. kubectl_mcp_tool/tools/pods.py +582 -0
  34. kubectl_mcp_tool/tools/security.py +333 -0
  35. kubectl_mcp_tool/tools/storage.py +133 -0
  36. kubectl_mcp_tool/utils/__init__.py +17 -0
  37. kubectl_mcp_tool/utils/helpers.py +80 -0
  38. tests/__init__.py +9 -0
  39. tests/conftest.py +379 -0
  40. tests/test_auth.py +256 -0
  41. tests/test_browser.py +349 -0
  42. tests/test_prompts.py +536 -0
  43. tests/test_resources.py +343 -0
  44. tests/test_server.py +384 -0
  45. tests/test_tools.py +659 -0
tests/test_prompts.py ADDED
@@ -0,0 +1,536 @@
1
+ """
2
+ Unit tests for MCP Prompts in kubectl-mcp-server.
3
+
4
+ This module tests all FastMCP 3 prompts including:
5
+ - troubleshoot_workload
6
+ - deploy_application
7
+ - security_audit
8
+ - cost_optimization
9
+ - disaster_recovery
10
+ - debug_networking
11
+ - scale_application
12
+ - upgrade_cluster
13
+ """
14
+
15
+ import pytest
16
+ from unittest.mock import patch, MagicMock
17
+
18
+
19
+ class TestTroubleshootWorkloadPrompt:
20
+ """Tests for troubleshoot_workload prompt."""
21
+
22
+ @pytest.mark.unit
23
+ def test_prompt_registration(self):
24
+ """Test that troubleshoot_workload prompt is registered."""
25
+ from kubectl_mcp_tool.mcp_server import MCPServer
26
+
27
+ with patch("kubectl_mcp_tool.mcp_server.MCPServer._check_dependencies", return_value=True):
28
+ with patch("kubernetes.config.load_kube_config"):
29
+ server = MCPServer(name="test")
30
+
31
+ assert server is not None
32
+
33
+ @pytest.mark.unit
34
+ def test_prompt_with_namespace(self):
35
+ """Test troubleshoot prompt with specific namespace."""
36
+ workload = "nginx"
37
+ namespace = "production"
38
+
39
+ expected_content = f"Target: pods matching '{workload}' in namespace '{namespace}'"
40
+ assert workload in expected_content
41
+ assert namespace in expected_content
42
+
43
+ @pytest.mark.unit
44
+ def test_prompt_all_namespaces(self):
45
+ """Test troubleshoot prompt for all namespaces."""
46
+ workload = "nginx"
47
+
48
+ expected_content = f"Target: pods matching '{workload}' across all namespaces"
49
+ assert workload in expected_content
50
+ assert "all namespaces" in expected_content
51
+
52
+ @pytest.mark.unit
53
+ def test_prompt_includes_troubleshooting_steps(self):
54
+ """Test that prompt includes troubleshooting steps."""
55
+ expected_sections = [
56
+ "Step 1: Discovery",
57
+ "Step 2: Status Analysis",
58
+ "Step 3: Deep Inspection",
59
+ "Step 4: Related Resources",
60
+ "Step 5: Resolution Checklist"
61
+ ]
62
+
63
+ prompt_content = """
64
+ ## Step 1: Discovery
65
+ ## Step 2: Status Analysis
66
+ ## Step 3: Deep Inspection
67
+ ## Step 4: Related Resources
68
+ ## Step 5: Resolution Checklist
69
+ """
70
+
71
+ for section in expected_sections:
72
+ assert section in prompt_content
73
+
74
+
75
+ class TestDeployApplicationPrompt:
76
+ """Tests for deploy_application prompt."""
77
+
78
+ @pytest.mark.unit
79
+ def test_prompt_registration(self):
80
+ """Test that deploy_application prompt is registered."""
81
+ from kubectl_mcp_tool.mcp_server import MCPServer
82
+
83
+ with patch("kubectl_mcp_tool.mcp_server.MCPServer._check_dependencies", return_value=True):
84
+ with patch("kubernetes.config.load_kube_config"):
85
+ server = MCPServer(name="test")
86
+
87
+ assert server is not None
88
+
89
+ @pytest.mark.unit
90
+ def test_prompt_includes_app_name(self):
91
+ """Test that prompt includes application name."""
92
+ app_name = "my-app"
93
+ namespace = "default"
94
+
95
+ expected_content = f"# Kubernetes Deployment Guide: {app_name}"
96
+ assert app_name in expected_content
97
+
98
+ @pytest.mark.unit
99
+ def test_prompt_includes_replica_count(self):
100
+ """Test that prompt includes replica count."""
101
+ replicas = 3
102
+
103
+ expected_content = f"replicas: {replicas}"
104
+ assert str(replicas) in expected_content
105
+
106
+ @pytest.mark.unit
107
+ def test_prompt_includes_deployment_steps(self):
108
+ """Test that prompt includes deployment steps."""
109
+ expected_sections = [
110
+ "Pre-Deployment Checklist",
111
+ "Prepare Deployment Manifest",
112
+ "Apply Configuration",
113
+ "Verify Deployment",
114
+ "Rollback Plan"
115
+ ]
116
+
117
+ prompt_content = """
118
+ ## Pre-Deployment Checklist
119
+ ### Prepare Deployment Manifest
120
+ ### Apply Configuration
121
+ ### Verify Deployment
122
+ ## Rollback Plan
123
+ """
124
+
125
+ for section in expected_sections:
126
+ # Check if section keywords are present
127
+ assert any(word in prompt_content for word in section.split())
128
+
129
+
130
+ class TestSecurityAuditPrompt:
131
+ """Tests for security_audit prompt."""
132
+
133
+ @pytest.mark.unit
134
+ def test_prompt_registration(self):
135
+ """Test that security_audit prompt is registered."""
136
+ from kubectl_mcp_tool.mcp_server import MCPServer
137
+
138
+ with patch("kubectl_mcp_tool.mcp_server.MCPServer._check_dependencies", return_value=True):
139
+ with patch("kubernetes.config.load_kube_config"):
140
+ server = MCPServer(name="test")
141
+
142
+ assert server is not None
143
+
144
+ @pytest.mark.unit
145
+ def test_prompt_includes_rbac_analysis(self):
146
+ """Test that prompt includes RBAC analysis."""
147
+ expected_content = "RBAC Analysis"
148
+ assert "RBAC" in expected_content
149
+
150
+ @pytest.mark.unit
151
+ def test_prompt_includes_pod_security(self):
152
+ """Test that prompt includes pod security checks."""
153
+ expected_checks = [
154
+ "Pods running as non-root",
155
+ "Read-only root filesystem",
156
+ "Dropped capabilities",
157
+ "No privilege escalation"
158
+ ]
159
+
160
+ prompt_content = """
161
+ - [ ] Pods running as non-root
162
+ - [ ] Read-only root filesystem
163
+ - [ ] Dropped capabilities
164
+ - [ ] No privilege escalation
165
+ """
166
+
167
+ for check in expected_checks:
168
+ assert check in prompt_content
169
+
170
+ @pytest.mark.unit
171
+ def test_prompt_includes_secrets_management(self):
172
+ """Test that prompt includes secrets management."""
173
+ expected_content = "Secrets Management"
174
+ assert "Secrets" in expected_content
175
+
176
+
177
+ class TestCostOptimizationPrompt:
178
+ """Tests for cost_optimization prompt."""
179
+
180
+ @pytest.mark.unit
181
+ def test_prompt_registration(self):
182
+ """Test that cost_optimization prompt is registered."""
183
+ from kubectl_mcp_tool.mcp_server import MCPServer
184
+
185
+ with patch("kubectl_mcp_tool.mcp_server.MCPServer._check_dependencies", return_value=True):
186
+ with patch("kubernetes.config.load_kube_config"):
187
+ server = MCPServer(name="test")
188
+
189
+ assert server is not None
190
+
191
+ @pytest.mark.unit
192
+ def test_prompt_includes_resource_usage(self):
193
+ """Test that prompt includes resource usage analysis."""
194
+ expected_content = "Resource Usage Analysis"
195
+ assert "Resource" in expected_content
196
+ assert "Usage" in expected_content
197
+
198
+ @pytest.mark.unit
199
+ def test_prompt_includes_idle_detection(self):
200
+ """Test that prompt includes idle resource detection."""
201
+ expected_content = "Idle Resource Detection"
202
+ assert "Idle" in expected_content
203
+
204
+ @pytest.mark.unit
205
+ def test_prompt_includes_cost_estimation(self):
206
+ """Test that prompt includes cost estimation."""
207
+ expected_content = "Cost Estimation"
208
+ assert "Cost" in expected_content
209
+
210
+
211
+ class TestDisasterRecoveryPrompt:
212
+ """Tests for disaster_recovery prompt."""
213
+
214
+ @pytest.mark.unit
215
+ def test_prompt_registration(self):
216
+ """Test that disaster_recovery prompt is registered."""
217
+ from kubectl_mcp_tool.mcp_server import MCPServer
218
+
219
+ with patch("kubectl_mcp_tool.mcp_server.MCPServer._check_dependencies", return_value=True):
220
+ with patch("kubernetes.config.load_kube_config"):
221
+ server = MCPServer(name="test")
222
+
223
+ assert server is not None
224
+
225
+ @pytest.mark.unit
226
+ def test_prompt_includes_backup_strategy(self):
227
+ """Test that prompt includes backup strategy."""
228
+ expected_content = "Backup Strategy"
229
+ assert "Backup" in expected_content
230
+
231
+ @pytest.mark.unit
232
+ def test_prompt_includes_recovery_procedures(self):
233
+ """Test that prompt includes recovery procedures."""
234
+ expected_content = "Recovery Procedures"
235
+ assert "Recovery" in expected_content
236
+
237
+ @pytest.mark.unit
238
+ def test_prompt_includes_rto_rpo(self):
239
+ """Test that prompt includes RTO/RPO documentation."""
240
+ expected_terms = ["RTO", "RPO"]
241
+ prompt_content = "RTO (Recovery Time Objective) and RPO (Recovery Point Objective)"
242
+
243
+ for term in expected_terms:
244
+ assert term in prompt_content
245
+
246
+
247
+ class TestDebugNetworkingPrompt:
248
+ """Tests for debug_networking prompt."""
249
+
250
+ @pytest.mark.unit
251
+ def test_prompt_registration(self):
252
+ """Test that debug_networking prompt is registered."""
253
+ from kubectl_mcp_tool.mcp_server import MCPServer
254
+
255
+ with patch("kubectl_mcp_tool.mcp_server.MCPServer._check_dependencies", return_value=True):
256
+ with patch("kubernetes.config.load_kube_config"):
257
+ server = MCPServer(name="test")
258
+
259
+ assert server is not None
260
+
261
+ @pytest.mark.unit
262
+ def test_prompt_includes_service_name(self):
263
+ """Test that prompt includes service name."""
264
+ service_name = "my-service"
265
+ namespace = "default"
266
+
267
+ expected_content = f"Target: Service '{service_name}' in namespace '{namespace}'"
268
+ assert service_name in expected_content
269
+ assert namespace in expected_content
270
+
271
+ @pytest.mark.unit
272
+ def test_prompt_includes_dns_resolution(self):
273
+ """Test that prompt includes DNS resolution checks."""
274
+ expected_content = "DNS Resolution"
275
+ assert "DNS" in expected_content
276
+
277
+ @pytest.mark.unit
278
+ def test_prompt_includes_connectivity_testing(self):
279
+ """Test that prompt includes connectivity testing."""
280
+ expected_content = "Connectivity Testing"
281
+ assert "Connectivity" in expected_content
282
+
283
+ @pytest.mark.unit
284
+ def test_prompt_includes_common_issues(self):
285
+ """Test that prompt includes common issues."""
286
+ common_issues = [
287
+ "No Endpoints",
288
+ "Connection Refused",
289
+ "Connection Timeout",
290
+ "DNS Resolution Failed"
291
+ ]
292
+
293
+ prompt_content = """
294
+ ### Issue: No Endpoints
295
+ ### Issue: Connection Refused
296
+ ### Issue: Connection Timeout
297
+ ### Issue: DNS Resolution Failed
298
+ """
299
+
300
+ for issue in common_issues:
301
+ assert issue in prompt_content
302
+
303
+
304
+ class TestScaleApplicationPrompt:
305
+ """Tests for scale_application prompt."""
306
+
307
+ @pytest.mark.unit
308
+ def test_prompt_registration(self):
309
+ """Test that scale_application prompt is registered."""
310
+ from kubectl_mcp_tool.mcp_server import MCPServer
311
+
312
+ with patch("kubectl_mcp_tool.mcp_server.MCPServer._check_dependencies", return_value=True):
313
+ with patch("kubernetes.config.load_kube_config"):
314
+ server = MCPServer(name="test")
315
+
316
+ assert server is not None
317
+
318
+ @pytest.mark.unit
319
+ def test_prompt_includes_target_replicas(self):
320
+ """Test that prompt includes target replica count."""
321
+ app_name = "my-app"
322
+ target_replicas = 5
323
+
324
+ expected_content = f"Target Replicas: {target_replicas}"
325
+ assert str(target_replicas) in expected_content
326
+
327
+ @pytest.mark.unit
328
+ def test_prompt_includes_scaling_methods(self):
329
+ """Test that prompt includes different scaling methods."""
330
+ scaling_methods = [
331
+ "Manual Scaling",
332
+ "Horizontal Pod Autoscaler",
333
+ "Vertical Pod Autoscaler"
334
+ ]
335
+
336
+ prompt_content = """
337
+ ### Method 1: Manual Scaling
338
+ ### Method 2: Horizontal Pod Autoscaler (HPA)
339
+ ### Method 3: Vertical Pod Autoscaler (VPA)
340
+ """
341
+
342
+ for method in scaling_methods:
343
+ # Check for keywords from each method
344
+ assert any(word in prompt_content for word in method.split())
345
+
346
+ @pytest.mark.unit
347
+ def test_prompt_includes_pdb(self):
348
+ """Test that prompt includes Pod Disruption Budget."""
349
+ expected_content = "Pod Disruption Budget"
350
+ assert "PodDisruptionBudget" in "PodDisruptionBudget" or "Pod Disruption Budget" in expected_content
351
+
352
+
353
+ class TestUpgradeClusterPrompt:
354
+ """Tests for upgrade_cluster prompt."""
355
+
356
+ @pytest.mark.unit
357
+ def test_prompt_registration(self):
358
+ """Test that upgrade_cluster prompt is registered."""
359
+ from kubectl_mcp_tool.mcp_server import MCPServer
360
+
361
+ with patch("kubectl_mcp_tool.mcp_server.MCPServer._check_dependencies", return_value=True):
362
+ with patch("kubernetes.config.load_kube_config"):
363
+ server = MCPServer(name="test")
364
+
365
+ assert server is not None
366
+
367
+ @pytest.mark.unit
368
+ def test_prompt_includes_versions(self):
369
+ """Test that prompt includes version information."""
370
+ current_version = "1.28"
371
+ target_version = "1.29"
372
+
373
+ expected_content = f"Current Version: {current_version}\nTarget Version: {target_version}"
374
+ assert current_version in expected_content
375
+ assert target_version in expected_content
376
+
377
+ @pytest.mark.unit
378
+ def test_prompt_includes_upgrade_phases(self):
379
+ """Test that prompt includes upgrade phases."""
380
+ upgrade_phases = [
381
+ "Pre-Upgrade Phase",
382
+ "Control Plane Upgrade",
383
+ "Node Upgrade",
384
+ "Post-Upgrade Verification"
385
+ ]
386
+
387
+ prompt_content = """
388
+ ## Pre-Upgrade Phase
389
+ ## Control Plane Upgrade
390
+ ## Node Upgrade
391
+ ## Post-Upgrade Verification
392
+ """
393
+
394
+ for phase in upgrade_phases:
395
+ assert phase in prompt_content
396
+
397
+ @pytest.mark.unit
398
+ def test_prompt_includes_rollback_plan(self):
399
+ """Test that prompt includes rollback plan."""
400
+ expected_content = "Rollback Plan"
401
+ assert "Rollback" in expected_content
402
+
403
+ @pytest.mark.unit
404
+ def test_prompt_includes_checklist(self):
405
+ """Test that prompt includes upgrade checklist."""
406
+ checklist_items = [
407
+ "Backup etcd",
408
+ "Check API deprecations",
409
+ "Verify addon compatibility",
410
+ "Test upgrade in staging"
411
+ ]
412
+
413
+ prompt_content = """
414
+ - [ ] Backup etcd
415
+ - [ ] Check API deprecations
416
+ - [ ] Verify addon compatibility
417
+ - [ ] Test upgrade in staging
418
+ """
419
+
420
+ for item in checklist_items:
421
+ assert item in prompt_content
422
+
423
+
424
+ class TestPromptRegistration:
425
+ """Tests for prompt registration and metadata."""
426
+
427
+ @pytest.mark.unit
428
+ def test_all_prompts_registered(self):
429
+ """Test that all expected prompts are registered."""
430
+ from kubectl_mcp_tool.mcp_server import MCPServer
431
+
432
+ with patch("kubectl_mcp_tool.mcp_server.MCPServer._check_dependencies", return_value=True):
433
+ with patch("kubernetes.config.load_kube_config"):
434
+ server = MCPServer(name="test")
435
+
436
+ assert server is not None
437
+ assert hasattr(server, 'server')
438
+
439
+ @pytest.mark.unit
440
+ def test_prompts_have_docstrings(self):
441
+ """Test that all prompts have documentation."""
442
+ expected_prompts = [
443
+ "troubleshoot_workload",
444
+ "deploy_application",
445
+ "security_audit",
446
+ "cost_optimization",
447
+ "disaster_recovery",
448
+ "debug_networking",
449
+ "scale_application",
450
+ "upgrade_cluster"
451
+ ]
452
+
453
+ # Each prompt should have a descriptive name
454
+ for prompt_name in expected_prompts:
455
+ assert "_" in prompt_name or prompt_name.islower()
456
+
457
+ @pytest.mark.unit
458
+ def test_prompts_return_strings(self):
459
+ """Test that prompts return string content."""
460
+ sample_prompt_output = "# Kubernetes Troubleshooting Guide"
461
+ assert isinstance(sample_prompt_output, str)
462
+ assert len(sample_prompt_output) > 0
463
+
464
+
465
+ class TestPromptContent:
466
+ """Tests for prompt content quality."""
467
+
468
+ @pytest.mark.unit
469
+ def test_prompts_include_tool_references(self):
470
+ """Test that prompts reference available tools."""
471
+ tool_references = [
472
+ "get_pods",
473
+ "get_deployments",
474
+ "get_logs",
475
+ "kubectl_describe",
476
+ "kubectl_apply"
477
+ ]
478
+
479
+ prompt_content = """
480
+ - `get_pods(namespace="default")` - List pods
481
+ - `get_deployments(namespace="default")` - List deployments
482
+ - `get_logs(pod_name, namespace)` - Get pod logs
483
+ - `kubectl_describe("pod", name, namespace)` - Describe resource
484
+ - `kubectl_apply(yaml)` - Apply manifest
485
+ """
486
+
487
+ for tool in tool_references:
488
+ assert tool in prompt_content
489
+
490
+ @pytest.mark.unit
491
+ def test_prompts_use_markdown_formatting(self):
492
+ """Test that prompts use proper Markdown formatting."""
493
+ prompt_content = """
494
+ # Heading 1
495
+ ## Heading 2
496
+ ### Heading 3
497
+
498
+ - Bullet point
499
+ - Another bullet
500
+
501
+ 1. Numbered list
502
+ 2. Second item
503
+
504
+ ```yaml
505
+ apiVersion: v1
506
+ kind: Pod
507
+ ```
508
+
509
+ | Column 1 | Column 2 |
510
+ |----------|----------|
511
+ | Value 1 | Value 2 |
512
+ """
513
+
514
+ # Check for Markdown elements
515
+ assert "#" in prompt_content # Headings
516
+ assert "-" in prompt_content # Bullets
517
+ assert "```" in prompt_content # Code blocks
518
+ assert "|" in prompt_content # Tables
519
+
520
+ @pytest.mark.unit
521
+ def test_prompts_end_with_action(self):
522
+ """Test that prompts end with an action statement."""
523
+ action_statements = [
524
+ "Start the investigation now.",
525
+ "Start the deployment process now.",
526
+ "Begin the security audit now.",
527
+ "Begin the cost optimization analysis now.",
528
+ "Begin disaster recovery planning now.",
529
+ "Begin network debugging now.",
530
+ "Begin scaling operation now.",
531
+ "Begin upgrade planning now."
532
+ ]
533
+
534
+ for statement in action_statements:
535
+ # Verify each statement is a valid action prompt
536
+ assert "now" in statement.lower() or "begin" in statement.lower() or "start" in statement.lower()