vmware-storage 2.4.2__tar.gz → 2.5.0__tar.gz
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.
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/.claude-plugin/plugin.json +2 -2
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/.mcp.json +1 -1
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/PKG-INFO +9 -7
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/README-CN.md +9 -6
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/README.md +8 -6
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/RELEASE_NOTES.md +7 -3
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/openclaw.plugin.json +2 -2
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/package.json +2 -2
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/pyproject.toml +1 -1
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/server.json +3 -3
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/skills/vmware-storage/SKILL.md +10 -7
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/skills/vmware-storage/references/agent-guardrails.md +1 -1
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/skills/vmware-storage/references/capabilities.md +5 -4
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/skills/vmware-storage/references/setup-guide.md +3 -3
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_audit_isolation.py +11 -4
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_datastore_list_renders.py +3 -1
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_storage_hardening_fixes.py +12 -12
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_vsan_efficiency.py +17 -0
- vmware_storage-2.5.0/tests/test_datastore_vm_usage.py +106 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/test_iscsi_gate.py +25 -17
- vmware_storage-2.5.0/tests/test_request_error_hints.py +29 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/uv.lock +7 -7
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/__init__.py +1 -1
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/access_requirements.py +1 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/mcp_server/server.py +70 -56
- vmware_storage-2.5.0/vmware_storage/ops/datastore_usage.py +136 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/ops/iscsi_gate.py +8 -13
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/ops/vsan.py +6 -2
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/ops/vsan_efficiency.py +13 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/.clawhubignore +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/.env.example +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/.gitignore +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/Dockerfile +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/LICENSE +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/SECURITY.md +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/config.example.yaml +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/docker-compose.yml +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/examples/mcp-configs/README.md +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/examples/mcp-configs/claude-code.json +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/examples/mcp-configs/continue.yaml +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/examples/mcp-configs/cursor.json +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/examples/mcp-configs/goose.json +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/examples/mcp-configs/localcowork.json +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/examples/mcp-configs/mcp-agent.yaml +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/examples/mcp-configs/vscode-copilot.json +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/patterns/README.md +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/patterns/iscsi-target-stale-rescan.yaml +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/skills/vmware-storage/evals/evals.json +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/skills/vmware-storage/references/cli-reference.md +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/smithery.yaml +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/__init__.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/conftest.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/__init__.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/capability/__init__.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/capability/_family.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/capability/_scores.json +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/capability/_scoring.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/capability/_skill.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/capability/conftest.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/capability/test_entity_reachability.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/capability/test_error_actionability.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/capability/test_tool_description_quality.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/capability/test_tool_manifest_budget.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/__init__.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_atexit_handlers_do_not_accumulate.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_browse_ds_path_join.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_browse_sees_every_file.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_cached_loader_agrees_with_the_resolver.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_capability_grader.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_cli_writes_guarded.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_credential_env_override.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_doctor_authenticates_every_target.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_doctor_uses_the_config_the_tools_use.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_env_secret_obfuscation.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_error_hints_fit_the_surface.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_fc_multipath.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_image_registry_cross_process.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_instructions_name_targets.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_inventory_scale_n1.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_iscsi_unreachable_host.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_list_cached_images_target.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_login_without_a_role.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_release_blockers.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_remedy_survives_a_long_home.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_result_envelope.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_returned_failure_is_audited.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_scan_populates_image_cache.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_session_probe_eviction.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_storage_ops_behavior.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_tool_names_2_0.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_vim_attribute_conformance.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_vsan_health_is_actually_queried.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_vsan_reports_what_it_could_not_read.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/spec/__init__.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/spec/vsan_efficiency_endpoints.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/spec/vsan_health_endpoints.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/test_access_info.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/test_filelock.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/test_init_and_onboarding.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/test_no_destructive_ops.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/test_no_destructive_vm_code.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/test_policy_roles.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/test_safe_error_passthrough.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/test_session_pool.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/test_stop_signal_runs_atexit.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/_filelock.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/cli.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/config.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/connection.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/doctor.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/init_wizard.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/mcp_server/__init__.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/mcp_server/__main__.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/notify/__init__.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/notify/audit.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/ops/__init__.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/ops/datastore_browser.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/ops/inventory.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/ops/iscsi_config.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/ops/multipath.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/ops/storage_paths.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/ops/vsan_sdk.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/policy_environment.py +0 -0
- {vmware_storage-2.4.2 → vmware_storage-2.5.0}/vmware_storage/policy_roles.py +0 -0
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
|
|
3
3
|
"name": "vmware-storage",
|
|
4
4
|
"displayName": "VMware Storage",
|
|
5
|
-
"version": "2.
|
|
6
|
-
"description": "VMware vSphere storage with
|
|
5
|
+
"version": "2.5.0",
|
|
6
|
+
"description": "VMware vSphere storage with 16 MCP tools: datastores, iSCSI, vSAN, FC multipath.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Wei Zhou",
|
|
9
9
|
"email": "zhouwei008@gmail.com",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vmware-storage
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: VMware vSphere storage management: datastores, iSCSI, vSAN. Domain-focused MCP skill.
|
|
5
5
|
Project-URL: Homepage, https://github.com/vmware-skills/VMware-Storage
|
|
6
6
|
Project-URL: Repository, https://github.com/vmware-skills/VMware-Storage
|
|
@@ -22,13 +22,15 @@ Description-Content-Type: text/markdown
|
|
|
22
22
|
<!-- mcp-name: io.github.vmware-skills/vmware-storage -->
|
|
23
23
|
# VMware Storage
|
|
24
24
|
|
|
25
|
+
For a read-only check of this skill with your model and agent host, use the shared [model-fit self-test](https://github.com/vmware-skills/marketplace/blob/main/MODEL_FIT_SELF_TEST.md) in the marketplace root.
|
|
26
|
+
|
|
25
27
|
> **Author**: Wei Zhou, VMware by Broadcom — wei-wz.zhou@broadcom.com
|
|
26
28
|
> This is a community-driven project by a VMware engineer, not an official VMware product.
|
|
27
29
|
> For official VMware developer tools see [developer.broadcom.com](https://developer.broadcom.com).
|
|
28
30
|
|
|
29
31
|
[English](README.md) | [中文](README-CN.md)
|
|
30
32
|
|
|
31
|
-
VMware vSphere storage management: datastores, iSCSI, vSAN, and read-only Fibre Channel / multipath diagnostics —
|
|
33
|
+
VMware vSphere storage management: datastores, iSCSI, vSAN, and read-only Fibre Channel / multipath diagnostics — 16 MCP tools, domain-focused and lightweight.
|
|
32
34
|
|
|
33
35
|
> Split from vmware-aiops for lighter context and local model compatibility.
|
|
34
36
|
|
|
@@ -109,11 +111,11 @@ chmod 600 ~/.vmware-storage/.env
|
|
|
109
111
|
vmware-storage doctor
|
|
110
112
|
```
|
|
111
113
|
|
|
112
|
-
## MCP Tools (
|
|
114
|
+
## MCP Tools (16)
|
|
113
115
|
|
|
114
116
|
| Category | Tools | Type |
|
|
115
117
|
|----------|-------|------|
|
|
116
|
-
| Datastore | `list_all_datastores`, `browse_datastore`, `scan_datastore_images`, `list_cached_images` | Read |
|
|
118
|
+
| Datastore | `list_all_datastores`, `get_datastore_vm_usage`, `browse_datastore`, `scan_datastore_images`, `list_cached_images` | Read |
|
|
117
119
|
| iSCSI | `enable_iscsi`, `get_iscsi_status`, `add_iscsi_target`, `remove_iscsi_target`, `rescan_storage` | Read/Write |
|
|
118
120
|
| vSAN | `get_vsan_health`, `get_vsan_capacity`, `get_vsan_efficiency` | Read |
|
|
119
121
|
| FC / multipath | `list_fc_adapters`, `list_storage_device_paths` | Read |
|
|
@@ -233,7 +235,7 @@ vmware-storage-mcp
|
|
|
233
235
|
|
|
234
236
|
`vmware-aiops` has 61 MCP tools — too heavy for local LLMs (7B-14B). By splitting storage into its own skill:
|
|
235
237
|
|
|
236
|
-
- **
|
|
238
|
+
- **16 tools** — fits comfortably in small model context windows
|
|
237
239
|
- **Domain-focused** — storage admins get only what they need
|
|
238
240
|
- **Least privilege** — can run under a vCenter service account with storage read-only permissions
|
|
239
241
|
- **Composable** — use alongside vmware-monitor or vmware-aiops as needed
|
|
@@ -260,8 +262,8 @@ vmware-storage-mcp
|
|
|
260
262
|
|
|
261
263
|
| Feature | Description |
|
|
262
264
|
|---------|-------------|
|
|
263
|
-
| Read-heavy |
|
|
264
|
-
| Preview by default (MCP) | The 4 write tools take `confirm` (default `false`): a call without it changes nothing and returns `blast_radius` (host, adapters, and for target removal the paths, devices and datastores behind the target). `confirm=true` is refused when a datastore would lose every path or part of the blast radius could not be read. `dry_run` is
|
|
265
|
+
| Read-heavy | 12/16 tools are read-only |
|
|
266
|
+
| Preview by default (MCP) | The 4 write tools take `confirm` (default `false`): a call without it changes nothing and returns `blast_radius` (host, adapters, and for target removal the paths, devices and datastores behind the target). `confirm=true` is refused when a datastore would lose every path or part of the blast radius could not be read. the old `dry_run` alias was removed in 2.4.3 and is refused as an unknown argument |
|
|
265
267
|
| Input validation | IP addresses and ports validated before iSCSI operations |
|
|
266
268
|
| Audit logging | All operations logged to `~/.vmware-storage/audit.log` |
|
|
267
269
|
| No VM operations | Cannot create, delete, or modify VMs |
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
<!-- mcp-name: io.github.vmware-skills/vmware-storage -->
|
|
2
2
|
# VMware Storage
|
|
3
3
|
|
|
4
|
+
要用自己的模型和 Agent 平台进行只读自测,请看 marketplace 根目录的[共享模型适配自测任务](https://github.com/vmware-skills/marketplace/blob/main/MODEL_FIT_SELF_TEST.md)。
|
|
5
|
+
|
|
4
6
|
> **作者**: Wei Zhou, VMware by Broadcom — wei-wz.zhou@broadcom.com
|
|
5
7
|
> 本项目由 VMware 工程师维护的社区项目,非 VMware 官方产品。
|
|
6
8
|
> VMware 官方开发者工具请访问 [developer.broadcom.com](https://developer.broadcom.com)。
|
|
7
9
|
|
|
8
10
|
[English](README.md) | [中文](README-CN.md)
|
|
9
11
|
|
|
10
|
-
VMware vSphere 存储管理:数据存储、iSCSI、vSAN,以及只读的光纤通道(FC)/ 多路径诊断 —
|
|
12
|
+
VMware vSphere 存储管理:数据存储、iSCSI、vSAN,以及只读的光纤通道(FC)/ 多路径诊断 — 16 个 MCP 工具,领域专注、轻量级。
|
|
11
13
|
|
|
12
14
|
> 从 vmware-aiops 拆分,更轻量的上下文,兼容本地小模型。
|
|
13
15
|
|
|
@@ -99,11 +101,11 @@ targets:
|
|
|
99
101
|
password_env: VMWARE_ESXIPROD_PASSWORD
|
|
100
102
|
```
|
|
101
103
|
|
|
102
|
-
## MCP 工具(
|
|
104
|
+
## MCP 工具(16 个)
|
|
103
105
|
|
|
104
106
|
| 类别 | 工具 | 类型 |
|
|
105
107
|
|------|------|------|
|
|
106
|
-
| 数据存储 | `list_all_datastores`、`browse_datastore`、`scan_datastore_images`、`list_cached_images` | 只读 |
|
|
108
|
+
| 数据存储 | `list_all_datastores`、`get_datastore_vm_usage`、`browse_datastore`、`scan_datastore_images`、`list_cached_images` | 只读 |
|
|
107
109
|
| iSCSI | `enable_iscsi`、`get_iscsi_status`、`add_iscsi_target`、`remove_iscsi_target`、`rescan_storage` | 读/写 |
|
|
108
110
|
| vSAN | `get_vsan_health`、`get_vsan_capacity`、`get_vsan_efficiency` | 只读 |
|
|
109
111
|
| FC / 多路径 | `list_fc_adapters`、`list_storage_device_paths` | 只读 |
|
|
@@ -113,6 +115,7 @@ targets:
|
|
|
113
115
|
|
|
114
116
|
**数据存储**
|
|
115
117
|
- `list_all_datastores` — 列出所有数据存储,含容量、使用率、可达性
|
|
118
|
+
- `get_datastore_vm_usage` — 一个数据存储上哪些虚拟机占得最多(实际占用 GB,从大到小),以及不属于任何虚拟机的空间
|
|
116
119
|
- `browse_datastore` — 浏览数据存储目录下的文件(支持 glob 过滤)
|
|
117
120
|
- `scan_datastore_images` — 扫描可部署镜像(OVA、ISO、OVF、VMDK)
|
|
118
121
|
- `list_cached_images` — 查询本地镜像注册表(支持按类型/数据存储/target 过滤)
|
|
@@ -251,7 +254,7 @@ vmware-storage-mcp
|
|
|
251
254
|
|
|
252
255
|
`vmware-aiops` 有 61 个 MCP 工具——对本地小模型(7B-14B)来说上下文占用太重。独立拆分后:
|
|
253
256
|
|
|
254
|
-
- **
|
|
257
|
+
- **16 个工具** — 完全适合小模型上下文窗口
|
|
255
258
|
- **领域专注** — 存储管理员只看到需要的工具
|
|
256
259
|
- **最小权限** — 可以配置只有存储只读权限的 vCenter 服务账号
|
|
257
260
|
- **可组合** — 可与 vmware-monitor 或 vmware-aiops 同时运行
|
|
@@ -270,8 +273,8 @@ vmware-storage-mcp
|
|
|
270
273
|
|
|
271
274
|
| 功能 | 说明 |
|
|
272
275
|
|------|------|
|
|
273
|
-
| 只读为主 |
|
|
274
|
-
| 默认只预览(MCP) | 4 个写工具接受 `confirm`(默认 `false`):不带它的调用不做任何变更,只返回 `blast_radius`(主机、适配器;移除目标时还有该目标背后的路径、设备和数据存储)。某个数据存储会失去全部路径、或影响范围有任何部分读不到时,`confirm=true`
|
|
276
|
+
| 只读为主 | 16 个工具中 12 个只读 |
|
|
277
|
+
| 默认只预览(MCP) | 4 个写工具接受 `confirm`(默认 `false`):不带它的调用不做任何变更,只返回 `blast_radius`(主机、适配器;移除目标时还有该目标背后的路径、设备和数据存储)。某个数据存储会失去全部路径、或影响范围有任何部分读不到时,`confirm=true` 会被拒绝。旧的 `dry_run` 别名已在 2.4.3 移除,仍传它会被当作未知参数拒绝 |
|
|
275
278
|
| 输入验证 | iSCSI 操作前验证 IP 地址和端口 |
|
|
276
279
|
| 审计日志 | 所有操作记录到 `~/.vmware-storage/audit.log`(JSON Lines) |
|
|
277
280
|
| 双重确认 | CLI iSCSI 写操作需两次确认 |
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
<!-- mcp-name: io.github.vmware-skills/vmware-storage -->
|
|
2
2
|
# VMware Storage
|
|
3
3
|
|
|
4
|
+
For a read-only check of this skill with your model and agent host, use the shared [model-fit self-test](https://github.com/vmware-skills/marketplace/blob/main/MODEL_FIT_SELF_TEST.md) in the marketplace root.
|
|
5
|
+
|
|
4
6
|
> **Author**: Wei Zhou, VMware by Broadcom — wei-wz.zhou@broadcom.com
|
|
5
7
|
> This is a community-driven project by a VMware engineer, not an official VMware product.
|
|
6
8
|
> For official VMware developer tools see [developer.broadcom.com](https://developer.broadcom.com).
|
|
7
9
|
|
|
8
10
|
[English](README.md) | [中文](README-CN.md)
|
|
9
11
|
|
|
10
|
-
VMware vSphere storage management: datastores, iSCSI, vSAN, and read-only Fibre Channel / multipath diagnostics —
|
|
12
|
+
VMware vSphere storage management: datastores, iSCSI, vSAN, and read-only Fibre Channel / multipath diagnostics — 16 MCP tools, domain-focused and lightweight.
|
|
11
13
|
|
|
12
14
|
> Split from vmware-aiops for lighter context and local model compatibility.
|
|
13
15
|
|
|
@@ -88,11 +90,11 @@ chmod 600 ~/.vmware-storage/.env
|
|
|
88
90
|
vmware-storage doctor
|
|
89
91
|
```
|
|
90
92
|
|
|
91
|
-
## MCP Tools (
|
|
93
|
+
## MCP Tools (16)
|
|
92
94
|
|
|
93
95
|
| Category | Tools | Type |
|
|
94
96
|
|----------|-------|------|
|
|
95
|
-
| Datastore | `list_all_datastores`, `browse_datastore`, `scan_datastore_images`, `list_cached_images` | Read |
|
|
97
|
+
| Datastore | `list_all_datastores`, `get_datastore_vm_usage`, `browse_datastore`, `scan_datastore_images`, `list_cached_images` | Read |
|
|
96
98
|
| iSCSI | `enable_iscsi`, `get_iscsi_status`, `add_iscsi_target`, `remove_iscsi_target`, `rescan_storage` | Read/Write |
|
|
97
99
|
| vSAN | `get_vsan_health`, `get_vsan_capacity`, `get_vsan_efficiency` | Read |
|
|
98
100
|
| FC / multipath | `list_fc_adapters`, `list_storage_device_paths` | Read |
|
|
@@ -212,7 +214,7 @@ vmware-storage-mcp
|
|
|
212
214
|
|
|
213
215
|
`vmware-aiops` has 61 MCP tools — too heavy for local LLMs (7B-14B). By splitting storage into its own skill:
|
|
214
216
|
|
|
215
|
-
- **
|
|
217
|
+
- **16 tools** — fits comfortably in small model context windows
|
|
216
218
|
- **Domain-focused** — storage admins get only what they need
|
|
217
219
|
- **Least privilege** — can run under a vCenter service account with storage read-only permissions
|
|
218
220
|
- **Composable** — use alongside vmware-monitor or vmware-aiops as needed
|
|
@@ -239,8 +241,8 @@ vmware-storage-mcp
|
|
|
239
241
|
|
|
240
242
|
| Feature | Description |
|
|
241
243
|
|---------|-------------|
|
|
242
|
-
| Read-heavy |
|
|
243
|
-
| Preview by default (MCP) | The 4 write tools take `confirm` (default `false`): a call without it changes nothing and returns `blast_radius` (host, adapters, and for target removal the paths, devices and datastores behind the target). `confirm=true` is refused when a datastore would lose every path or part of the blast radius could not be read. `dry_run` is
|
|
244
|
+
| Read-heavy | 12/16 tools are read-only |
|
|
245
|
+
| Preview by default (MCP) | The 4 write tools take `confirm` (default `false`): a call without it changes nothing and returns `blast_radius` (host, adapters, and for target removal the paths, devices and datastores behind the target). `confirm=true` is refused when a datastore would lose every path or part of the blast radius could not be read. the old `dry_run` alias was removed in 2.4.3 and is refused as an unknown argument |
|
|
244
246
|
| Input validation | IP addresses and ports validated before iSCSI operations |
|
|
245
247
|
| Audit logging | All operations logged to `~/.vmware-storage/audit.log` |
|
|
246
248
|
| No VM operations | Cannot create, delete, or modify VMs |
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## v2.5.0 — per-VM datastore usage and clearer storage refusals (2026-11-01)
|
|
2
|
+
|
|
3
|
+
* New read-only `get_datastore_vm_usage(datastore_name, top_n=10)` reports per-VM committed, uncommitted and unshared space on one datastore, plus attributed/unattributed used space and VMs whose usage could not be measured. It uses one PropertyCollector pass, sorts largest committed usage first, and does not turn unknown into zero. The MCP surface now has 16 tools. Verified against a lab vCenter before this release branch.
|
|
4
|
+
* An unknown cluster or invalid storage path now returns the specific corrective hint instead of a generic connection hint. On a cluster without vSAN, `get_vsan_efficiency` reports both feature flags as unknown and says vSAN is disabled.
|
|
5
|
+
* Removed the deprecated MCP `dry_run` alias from the destructive tools. Use `confirm=False` for a no-write preview and `confirm=True` after reviewing its blast radius; clients still passing `dry_run` must update.
|
|
6
|
+
|
|
1
7
|
## v2.4.2 — a login refused for lack of a vSphere role says so (2026-10-19)
|
|
2
8
|
|
|
3
9
|
* **A login vCenter refuses with `NoPermission` gets the role error, not the raw fault.** Found on a vCenter 8.0.3
|
|
@@ -8,8 +14,6 @@
|
|
|
8
14
|
neutral text naming the (sanitized) privilege. A wrong password (`InvalidLogin`) is unchanged. Same text as
|
|
9
15
|
vmware-monitor.
|
|
10
16
|
|
|
11
|
-
## Unreleased — follow-ups to the 2.4.1 review
|
|
12
|
-
|
|
13
17
|
* **`list_cached_images(target=...)`** returns one target's cached images; without it, nothing changes.
|
|
14
18
|
* The cache write takes a lock across processes, so a CLI and an MCP scan at the same time keep both sides' rows; a
|
|
15
19
|
lock held for more than 10 s is reported in `cache_note` with the lock file's path.
|
|
@@ -1512,4 +1516,4 @@ Domain-focused VMware storage skill, split from vmware-aiops for lighter context
|
|
|
1512
1516
|
|
|
1513
1517
|
### Datastore Management / 数据存储管理
|
|
1514
1518
|
|
|
1515
|
-
- `list_all_datastores` — List all datastores with capacity, usage
|
|
1519
|
+
- `list_all_datastores` — List all datastores with capacity, usage
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "vmware-storage",
|
|
3
3
|
"name": "VMware Storage",
|
|
4
|
-
"description": "VMware vSphere storage with
|
|
4
|
+
"description": "VMware vSphere storage with 16 MCP tools: datastores, iSCSI, vSAN, FC multipath.",
|
|
5
5
|
"skills": [
|
|
6
6
|
"./skills"
|
|
7
7
|
],
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"command": "uvx",
|
|
12
12
|
"args": [
|
|
13
13
|
"--from",
|
|
14
|
-
"vmware-storage==2.
|
|
14
|
+
"vmware-storage==2.5.0",
|
|
15
15
|
"vmware-storage-mcp"
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zw008/vmware-storage",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "VMware vSphere storage with
|
|
3
|
+
"version": "2.5.0",
|
|
4
|
+
"description": "VMware vSphere storage with 16 MCP tools: datastores, iSCSI, vSAN, FC multipath.",
|
|
5
5
|
"private": true,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://github.com/vmware-skills/VMware-Storage",
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.vmware-skills/vmware-storage",
|
|
4
4
|
"title": "VMware Storage",
|
|
5
|
-
"description": "VMware vSphere storage with
|
|
5
|
+
"description": "VMware vSphere storage with 16 MCP tools: datastores, iSCSI, vSAN, FC multipath.",
|
|
6
6
|
"repository": {
|
|
7
7
|
"url": "https://github.com/vmware-skills/VMware-Storage",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.
|
|
10
|
+
"version": "2.5.0",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "pypi",
|
|
14
14
|
"identifier": "vmware-storage",
|
|
15
|
-
"version": "2.
|
|
15
|
+
"version": "2.5.0",
|
|
16
16
|
"runtimeHint": "uvx",
|
|
17
17
|
"packageArguments": [
|
|
18
18
|
{
|
|
@@ -19,9 +19,11 @@ compatibility: >
|
|
|
19
19
|
|
|
20
20
|
# VMware Storage
|
|
21
21
|
|
|
22
|
+
> Self-test: [guide](https://github.com/vmware-skills/marketplace/blob/main/MODEL_FIT_SELF_TEST.md).
|
|
23
|
+
|
|
22
24
|
> **Disclaimer**: This is a community-maintained open-source project and is **not affiliated with, endorsed by, or sponsored by VMware, Inc. or Broadcom Inc.** "VMware" and "vSphere" are trademarks of Broadcom. Source code is publicly auditable at [github.com/vmware-skills/VMware-Storage](https://github.com/vmware-skills/VMware-Storage) under the MIT license.
|
|
23
25
|
|
|
24
|
-
VMware vSphere storage management —
|
|
26
|
+
VMware vSphere storage management — 16 MCP tools for datastores, iSCSI, vSAN, Fibre Channel / multipath diagnostics, and an access self-check.
|
|
25
27
|
|
|
26
28
|
> Split from vmware-aiops for lighter context and local model compatibility.
|
|
27
29
|
> **Companion skills**: [vmware-aiops](https://github.com/vmware-skills/VMware-AIops) (VM lifecycle), [vmware-monitor](https://github.com/vmware-skills/VMware-Monitor) (read-only monitoring), [vmware-vks](https://github.com/vmware-skills/VMware-VKS) (Tanzu Kubernetes), [vmware-nsx](https://github.com/vmware-skills/VMware-NSX) (NSX networking), [vmware-nsx-security](https://github.com/vmware-skills/VMware-NSX-Security) (DFW/firewall), [vmware-aria](https://github.com/vmware-skills/VMware-Aria) (metrics/alerts/capacity), [vmware-avi](https://github.com/vmware-skills/VMware-AVI) (AVI/ALB/AKO), [vmware-harden](https://github.com/vmware-skills/VMware-Harden) (compliance baselines).
|
|
@@ -40,7 +42,7 @@ VMware vSphere storage management — 15 MCP tools for datastores, iSCSI, vSAN,
|
|
|
40
42
|
## Quick Install
|
|
41
43
|
|
|
42
44
|
```bash
|
|
43
|
-
uv tool install vmware-storage==2.
|
|
45
|
+
uv tool install vmware-storage==2.5.0
|
|
44
46
|
vmware-storage init # guided setup: writes config + .env (chmod 600, password grep-safe), then verifies
|
|
45
47
|
vmware-storage doctor
|
|
46
48
|
```
|
|
@@ -147,15 +149,16 @@ vmware-storage iscsi status esxi-lab --target lab-esxi
|
|
|
147
149
|
| Cloud models (Claude, GPT-4o) | Either | MCP gives structured JSON I/O |
|
|
148
150
|
| Automated pipelines | **MCP** | Type-safe parameters, structured output |
|
|
149
151
|
|
|
150
|
-
## MCP Tools (
|
|
152
|
+
## MCP Tools (16 — 12 read, 4 write)
|
|
151
153
|
|
|
152
|
-
All MCP tools accept an optional `target` parameter to select which vCenter/ESXi to connect to. The 4 write tools take `confirm` (default false): without it they change nothing and return `blast_radius` — the host and adapters touched, and for `remove_iscsi_target` the paths, devices and datastores behind the target. Show it to the user; pass `confirm: true` only after they decide. `dry_run` is
|
|
154
|
+
All MCP tools accept an optional `target` parameter to select which vCenter/ESXi to connect to. The 4 write tools take `confirm` (default false): without it they change nothing and return `blast_radius` — the host and adapters touched, and for `remove_iscsi_target` the paths, devices and datastores behind the target. Show it to the user; pass `confirm: true` only after they decide. the old `dry_run` alias was removed in 2.4.3 and is refused as an unknown argument.
|
|
153
155
|
|
|
154
156
|
The four Datastore read tools return the family list envelope — `{items, returned, limit, total, truncated, hint}` — rather than a bare array. Read the rows from `items`; `truncated` says whether the listing is complete, so it never has to be guessed from the row count. All four enumerate their collection in full, so `total` is the real count and `truncated` is always `false`.
|
|
155
157
|
|
|
156
158
|
| Category | Tool | Type | Description |
|
|
157
159
|
|----------|------|:----:|-------------|
|
|
158
160
|
| Datastore | `list_all_datastores` | Read | List datastores with capacity, usage %, VM count |
|
|
161
|
+
| | `get_datastore_vm_usage` | Read | Which VMs take the space on one datastore (committed GB, largest first) and how much no VM accounts for |
|
|
159
162
|
| | `browse_datastore` | Read | Browse files with optional path and glob pattern |
|
|
160
163
|
| | `scan_datastore_images` | Read | Find OVA/ISO/OVF/VMDK in a datastore |
|
|
161
164
|
| | `list_cached_images` | Read | Query local image registry with type/datastore/target filters |
|
|
@@ -171,7 +174,7 @@ The four Datastore read tools return the family list envelope — `{items, retur
|
|
|
171
174
|
| | `list_storage_device_paths` | Read | Per-device path state across a cluster/host/datastore; visibility and path-count differences |
|
|
172
175
|
| Access | `get_access_info` | Read | Account in use and, per tool, whether its privileges are granted on the root folder |
|
|
173
176
|
|
|
174
|
-
**Read/write split**:
|
|
177
|
+
**Read/write split**: 12 tools are read-only, 4 modify state. Write tools require explicit parameters (host name, IP address), preview unless `confirm: true`, refuse when a datastore would lose every path or the host's storage view cannot be read, and are audit-logged. `remove_iscsi_target` is classified `risk:high` (destructive — LUNs can become inaccessible) and goes through the policy confirmation gate.
|
|
175
178
|
|
|
176
179
|
Running with local or small models? See [`references/agent-guardrails.md`](references/agent-guardrails.md).
|
|
177
180
|
|
|
@@ -257,7 +260,7 @@ Corporate TLS proxies inject certificates that uv's bundled CA store doesn't tru
|
|
|
257
260
|
## Safety
|
|
258
261
|
|
|
259
262
|
- **No VM operations**: This skill cannot power on/off, create, delete, or modify VMs — that scope belongs to `vmware-aiops`
|
|
260
|
-
- **Read-heavy**:
|
|
263
|
+
- **Read-heavy**: 12 of 16 tools are read-only (list, per-VM usage, browse, scan, cached images, status, health, capacity, efficiency, FC adapters, device paths, access info)
|
|
261
264
|
- **Audit logging**: All operations (including reads) are logged to `~/.vmware/audit.db` (SQLite WAL, via vmware-policy) with timestamp, user, target, operation, parameters, and result
|
|
262
265
|
- **Double confirmation**: CLI write commands (iSCSI enable, add/remove target) require two separate "Are you sure?" prompts before executing
|
|
263
266
|
- **Dry-run mode**: All write commands support `--dry-run` to preview API calls without executing
|
|
@@ -271,7 +274,7 @@ Corporate TLS proxies inject certificates that uv's bundled CA store doesn't tru
|
|
|
271
274
|
## Setup
|
|
272
275
|
|
|
273
276
|
```bash
|
|
274
|
-
uv tool install vmware-storage==2.
|
|
277
|
+
uv tool install vmware-storage==2.5.0
|
|
275
278
|
mkdir -p ~/.vmware-storage
|
|
276
279
|
cp config.example.yaml ~/.vmware-storage/config.yaml
|
|
277
280
|
# Edit config.yaml with your vCenter/ESXi targets
|
{vmware_storage-2.4.2 → vmware_storage-2.5.0}/skills/vmware-storage/references/agent-guardrails.md
RENAMED
|
@@ -14,7 +14,7 @@ vmware-monitor and vmware-aria against a production vSphere estate with Llama
|
|
|
14
14
|
cross-skill rules are identical across this family; the parts below marked
|
|
15
15
|
vmware-storage are specific to this skill.
|
|
16
16
|
|
|
17
|
-
vmware-storage exposes
|
|
17
|
+
vmware-storage exposes 16 MCP tools, 4 of which change state. The write
|
|
18
18
|
surface is small but sharp: removing an iSCSI send target can make LUNs — and
|
|
19
19
|
every VM living on them — inaccessible.
|
|
20
20
|
|
{vmware_storage-2.4.2 → vmware_storage-2.5.0}/skills/vmware-storage/references/capabilities.md
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# VMware Storage Capabilities
|
|
2
2
|
|
|
3
|
-
All
|
|
3
|
+
All 16 MCP tools exposed by `vmware-storage-mcp`, organized by category.
|
|
4
4
|
|
|
5
5
|
## Automation Level Reference
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ Each operation is classified by autonomy level per the Enterprise Harness Engine
|
|
|
8
8
|
|
|
9
9
|
| Level | Meaning | Agent autonomy | Examples in this skill |
|
|
10
10
|
|:-:|---|---|---|
|
|
11
|
-
| **L1** | Read-only, raw data | Always auto-run | `list_all_datastores`, `browse_datastore`, `scan_datastore_images`, `list_cached_images`, `get_iscsi_status`, vSAN status queries |
|
|
11
|
+
| **L1** | Read-only, raw data | Always auto-run | `list_all_datastores`, `get_datastore_vm_usage`, `browse_datastore`, `scan_datastore_images`, `list_cached_images`, `get_iscsi_status`, vSAN status queries |
|
|
12
12
|
| **L2** | Read + analysis / recommendation | Always auto-run | datastore capacity analysis, image registry queries, iSCSI target health correlation |
|
|
13
13
|
| **L3** | Single write — user must approve | Only after explicit confirmation; high-risk ops require double-confirm + `--dry-run` (see Confirm column) | `enable_iscsi`, `add_iscsi_target`, `remove_iscsi_target`, vSAN cluster ops |
|
|
14
14
|
| **L4** | Multi-step plan / apply workflow | Plan generation auto; apply gated by user approval | *(roadmap — multi-host iSCSI rollout, vSAN expansion plans)* |
|
|
@@ -24,6 +24,7 @@ Each operation is classified by autonomy level per the Enterprise Harness Engine
|
|
|
24
24
|
| Tool | Description | Parameters | Risk | Confirm |
|
|
25
25
|
|------|-------------|------------|:----:|:-------:|
|
|
26
26
|
| `list_all_datastores` | List datastores with capacity, usage %, VM count | `target` (string, optional), `limit` (int, optional; omit for all) | Low | No |
|
|
27
|
+
| `get_datastore_vm_usage` | Per-VM space on one datastore: committed / uncommitted / unshared GB, largest first, plus `unattributed_gb` (used space no VM accounts for) and `unmeasured_vms` | `datastore_name` (string, **required**), `top_n` (int, optional, default 10), `target` (string, optional) | Low | No |
|
|
27
28
|
| `browse_datastore` | Browse files with optional path and glob pattern | `datastore_name` (string, **required**), `path` (string, optional), `pattern` (string, optional), `target` (string, optional) | Low | No |
|
|
28
29
|
| `scan_datastore_images` | Find OVA/ISO/OVF/VMDK deployable images in a datastore | `datastore_name` (string, **required**), `target` (string, optional) | Low | No |
|
|
29
30
|
| `list_cached_images` | Query local image registry with type/datastore/target filters | `image_type` (string, optional), `datastore` (string, optional), `target` (string, optional) | Low | No |
|
|
@@ -108,7 +109,7 @@ Source: each host's `config.storageDevice` (HBAs, SCSI LUNs, `multipathInfo`) an
|
|
|
108
109
|
|
|
109
110
|
## Audit Coverage
|
|
110
111
|
|
|
111
|
-
All
|
|
112
|
+
All 16 tools are wrapped with `@vmware_tool` from vmware-policy, which provides:
|
|
112
113
|
|
|
113
114
|
- **Pre-execution**: Policy rule check against `~/.vmware/rules.yaml` (deny rules, maintenance windows)
|
|
114
115
|
- **Post-execution**: Audit log entry written to `~/.vmware/audit.db` (SQLite WAL mode)
|
|
@@ -118,7 +119,7 @@ All 15 tools are wrapped with `@vmware_tool` from vmware-policy, which provides:
|
|
|
118
119
|
|
|
119
120
|
| Type | Count | Tools |
|
|
120
121
|
|------|:-----:|-------|
|
|
121
|
-
| Read |
|
|
122
|
+
| Read | 11 | `list_all_datastores`, `get_datastore_vm_usage`, `browse_datastore`, `scan_datastore_images`, `list_cached_images`, `get_iscsi_status`, `get_vsan_health`, `get_vsan_capacity`, `get_vsan_efficiency`, `list_fc_adapters`, `list_storage_device_paths` |
|
|
122
123
|
| Write | 4 | `enable_iscsi`, `add_iscsi_target`, `remove_iscsi_target`, `rescan_storage` |
|
|
123
124
|
|
|
124
125
|
> Write tools require explicit parameters (host name, IP address) and support `--dry-run` in CLI mode. Over MCP they preview by default: without `confirm: true` they return `blast_radius` and change nothing. All write operations are audit-logged with timestamp, user, target, operation, parameters, and result.
|
{vmware_storage-2.4.2 → vmware_storage-2.5.0}/skills/vmware-storage/references/setup-guide.md
RENAMED
|
@@ -13,19 +13,19 @@ Complete setup and security guide for `vmware-storage`.
|
|
|
13
13
|
### Via uv (recommended)
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
uv tool install vmware-storage==2.
|
|
16
|
+
uv tool install vmware-storage==2.5.0
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
### Via pip
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
pip install vmware-storage==2.
|
|
22
|
+
pip install vmware-storage==2.5.0
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
### From source
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
git clone --branch v2.
|
|
28
|
+
git clone --branch v2.5.0 https://github.com/vmware-skills/VMware-Storage.git
|
|
29
29
|
cd VMware-Storage
|
|
30
30
|
pip install -e .
|
|
31
31
|
```
|
|
@@ -121,10 +121,17 @@ def test_an_audited_write_lands_in_the_sandbox_and_not_in_the_real_db() -> None:
|
|
|
121
121
|
real_db = REAL_HOME / ".vmware" / "audit.db"
|
|
122
122
|
if not real_db.exists():
|
|
123
123
|
pytest.skip("no production audit database on this machine to check against")
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
try:
|
|
125
|
+
with sqlite3.connect(f"file:{real_db}?mode=ro", uri=True) as con:
|
|
126
|
+
leaked = con.execute(
|
|
127
|
+
"SELECT count(*) FROM audit_log WHERE tool = ?", (marker,)
|
|
128
|
+
).fetchone()[0]
|
|
129
|
+
except sqlite3.OperationalError as exc:
|
|
130
|
+
# A restricted runner may see the file but have no permission to open it.
|
|
131
|
+
# The sandbox write assertion above still ran; this external check did not.
|
|
132
|
+
if "unable to open database file" in str(exc):
|
|
133
|
+
pytest.skip("production audit database is outside this runner's readable roots")
|
|
134
|
+
raise
|
|
128
135
|
assert leaked == 0, (
|
|
129
136
|
f"{leaked} row(s) from this test reached the operator's audit database "
|
|
130
137
|
f"at {real_db}"
|
{vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_datastore_list_renders.py
RENAMED
|
@@ -88,7 +88,9 @@ def test_a_datastore_over_the_threshold_is_still_styled_red() -> None:
|
|
|
88
88
|
assert cool.style != "red"
|
|
89
89
|
|
|
90
90
|
# ...and the style survives to the terminal, not just the object.
|
|
91
|
-
|
|
91
|
+
# The runner may set TERM=dumb or NO_COLOR=1. Test Rich's colour rendering
|
|
92
|
+
# explicitly, independent of the surrounding terminal policy.
|
|
93
|
+
console = Console(force_terminal=True, color_system="standard", no_color=False, width=40)
|
|
92
94
|
with console.capture() as cap:
|
|
93
95
|
console.print(hot)
|
|
94
96
|
assert "\x1b[31m" in cap.get()
|
{vmware_storage-2.4.2 → vmware_storage-2.5.0}/tests/eval/regression/test_storage_hardening_fixes.py
RENAMED
|
@@ -101,11 +101,11 @@ def test_iscsi_status_risk_level_is_low():
|
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
@pytest.mark.parametrize("tool_name", _WRITE_TOOLS)
|
|
104
|
-
def
|
|
105
|
-
"""HLD §7: ``confirm`` defaults to False; ``dry_run`` is
|
|
104
|
+
def test_write_tools_take_confirm_and_no_dry_run(tool_name):
|
|
105
|
+
"""HLD §7: ``confirm`` defaults to False; the ``dry_run`` alias is gone (2.4.3).
|
|
106
106
|
|
|
107
107
|
Until the confirmation gate, ``dry_run`` defaulted to False, so a bare call
|
|
108
|
-
acted.
|
|
108
|
+
acted. It was a deprecated alias for one minor cycle and is now removed.
|
|
109
109
|
"""
|
|
110
110
|
import inspect
|
|
111
111
|
|
|
@@ -114,7 +114,7 @@ def test_write_tools_take_confirm_and_keep_dry_run_as_alias(tool_name):
|
|
|
114
114
|
fn = getattr(server, tool_name)
|
|
115
115
|
sig = inspect.signature(inspect.unwrap(fn))
|
|
116
116
|
assert sig.parameters["confirm"].default is False
|
|
117
|
-
assert
|
|
117
|
+
assert "dry_run" not in sig.parameters
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
@pytest.mark.parametrize(
|
|
@@ -126,8 +126,8 @@ def test_write_tools_take_confirm_and_keep_dry_run_as_alias(tool_name):
|
|
|
126
126
|
("rescan_storage", {"host_name": "esxi-01"}),
|
|
127
127
|
],
|
|
128
128
|
)
|
|
129
|
-
def
|
|
130
|
-
"""
|
|
129
|
+
def test_a_bare_call_previews_without_writing(tool_name, kwargs, monkeypatch):
|
|
130
|
+
"""A call without confirm must return a preview and never reach an executor.
|
|
131
131
|
|
|
132
132
|
It used to return a canned string without connecting. The preview now
|
|
133
133
|
measures the blast radius (HLD §7), which needs the connection, so the
|
|
@@ -138,7 +138,7 @@ def test_dry_run_previews_without_writing(tool_name, kwargs, monkeypatch):
|
|
|
138
138
|
from vmware_storage.mcp_server import server
|
|
139
139
|
|
|
140
140
|
def explode(*a, **k): # pragma: no cover - failure path
|
|
141
|
-
raise AssertionError("a
|
|
141
|
+
raise AssertionError("a preview must not reach an executor")
|
|
142
142
|
|
|
143
143
|
radius = {"already_enabled": False, "already_configured": False,
|
|
144
144
|
"blockers": [], "unmeasured": []}
|
|
@@ -152,9 +152,9 @@ def test_dry_run_previews_without_writing(tool_name, kwargs, monkeypatch):
|
|
|
152
152
|
"_ops_remove_iscsi_target", "_ops_rescan_storage"):
|
|
153
153
|
monkeypatch.setattr(server, executor, explode)
|
|
154
154
|
fn = inspect.unwrap(getattr(server, tool_name))
|
|
155
|
-
result = fn(
|
|
155
|
+
result = fn(**kwargs)
|
|
156
156
|
assert result["action"] == "preview"
|
|
157
|
-
assert "
|
|
157
|
+
assert "deprecated" not in result
|
|
158
158
|
|
|
159
159
|
|
|
160
160
|
# ── Fix 3: audit failure must not flip a successful write ──────────────────
|
|
@@ -232,12 +232,12 @@ def _list_tools():
|
|
|
232
232
|
return asyncio.run(mcp.list_tools())
|
|
233
233
|
|
|
234
234
|
|
|
235
|
-
def
|
|
235
|
+
def test_mcp_exposes_16_tools_12_read_4_write():
|
|
236
236
|
tools = _list_tools()
|
|
237
|
-
assert len(tools) ==
|
|
237
|
+
assert len(tools) == 16, f"Expected 16 MCP tools, got {len(tools)}: {[t.name for t in tools]}"
|
|
238
238
|
read = [t.name for t in tools if t.annotations and t.annotations.readOnlyHint]
|
|
239
239
|
write = [t.name for t in tools if not (t.annotations and t.annotations.readOnlyHint)]
|
|
240
|
-
assert len(read) ==
|
|
240
|
+
assert len(read) == 12, f"Expected 12 read tools, got {len(read)}: {read}"
|
|
241
241
|
assert len(write) == 4, f"Expected 4 write tools, got {len(write)}: {write}"
|
|
242
242
|
assert sorted(write) == sorted(_WRITE_TOOLS)
|
|
243
243
|
|
|
@@ -178,6 +178,23 @@ def test_efficiency_absent_fields_do_not_crash(patched, monkeypatch):
|
|
|
178
178
|
assert result["compression_enabled"] is None
|
|
179
179
|
|
|
180
180
|
|
|
181
|
+
def test_vsan_off_reports_both_flags_as_not_applicable(patched, monkeypatch):
|
|
182
|
+
# 2026-10-24, 8.0.3 lab, vSAN off: the SDK answered dedupEnabled=False with
|
|
183
|
+
# compressionEnabled absent, so the tool said dedup "off" and compression
|
|
184
|
+
# "unknown" about a feature that does not apply.
|
|
185
|
+
config = SimpleNamespace(
|
|
186
|
+
enabled=False,
|
|
187
|
+
dataEfficiencyConfig=SimpleNamespace(dedupEnabled=False),
|
|
188
|
+
)
|
|
189
|
+
monkeypatch.setattr(ops, "_config_system", lambda si: _config_system_returning(config))
|
|
190
|
+
|
|
191
|
+
result = ops.get_vsan_efficiency(object(), "prod-cluster")
|
|
192
|
+
|
|
193
|
+
assert result["vsan_enabled"] is False
|
|
194
|
+
assert result["dedup_enabled"] is None and result["compression_enabled"] is None
|
|
195
|
+
assert result["message"] == "vSAN is not enabled on cluster 'prod-cluster'"
|
|
196
|
+
|
|
197
|
+
|
|
181
198
|
def test_config_system_teaches_when_stub_absent(monkeypatch):
|
|
182
199
|
# A session with no _stub gets a teaching VSANError, not an AttributeError.
|
|
183
200
|
# VSANError is imported from its home now that vsan_efficiency no longer
|