vmware-aria 2.4.0__tar.gz → 2.4.2__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_aria-2.4.0 → vmware_aria-2.4.2}/.claude-plugin/plugin.json +1 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/.mcp.json +1 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/PKG-INFO +5 -3
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/README-CN.md +3 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/README.md +3 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/RELEASE_NOTES.md +30 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/openclaw.plugin.json +1 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/package.json +1 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/pyproject.toml +2 -2
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/server.json +2 -2
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/skills/vmware-aria/SKILL.md +5 -3
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/skills/vmware-aria/references/agent-guardrails.md +4 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/skills/vmware-aria/references/capabilities.md +1 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/skills/vmware-aria/references/cli-reference.md +5 -2
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/skills/vmware-aria/references/setup-guide.md +34 -4
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_a_9x_only_404_is_not_a_bad_id.py +3 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_metrics_summary.py +60 -0
- vmware_aria-2.4.2/tests/test_error_hints.py +52 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/test_gated_writes.py +20 -15
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/test_init_and_onboarding.py +14 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/test_investigate.py +25 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/test_policy_roles.py +27 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/uv.lock +13 -13
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/__init__.py +1 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/cli.py +1 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/connection.py +17 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/_shared.py +35 -5
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/server.py +9 -20
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/alert_definitions.py +2 -2
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/alert_workflow.py +3 -5
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/alerts.py +7 -6
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/anomaly.py +2 -2
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/api.py +1 -2
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/capacity.py +4 -4
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/catalog.py +3 -4
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/fleet.py +5 -7
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/health.py +4 -4
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/maintenance.py +5 -12
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/reports.py +4 -4
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/resources.py +8 -6
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/investigate.py +38 -2
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/metric_summary.py +24 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/resources.py +1 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/write_gate.py +6 -15
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/policy_roles.py +6 -1
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/.clawhubignore +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/.env.example +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/.gitignore +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/Dockerfile +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/SECURITY.md +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/config.example.yaml +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/docker-compose.yml +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/examples/mcp-configs/claude-code.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/examples/mcp-configs/cursor.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/examples/mcp-configs/goose.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/skills/vmware-aria/evals/evals.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/skills/vmware-aria/references/investigation-protocol.md +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/skills/vmware-aria/references/ops-playbooks.md +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/smithery.yaml +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/__init__.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/conftest.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/__init__.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/capability/__init__.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/capability/_family.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/capability/_scores.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/capability/_scoring.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/capability/_skill.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/capability/conftest.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/capability/test_entity_reachability.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/capability/test_error_actionability.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/capability/test_tool_description_quality.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/capability/test_tool_manifest_budget.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/alert_adapter_childs_no_data.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/alert_notes_404.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/alert_notes_empty.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/alert_vcapp_health.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/alertdefinition_adapter_childs_no_data.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/alertdefinition_vcapp_health.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/contributingsymptoms_vcapp_health.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/host_relationships_all.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/host_relationships_child.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/host_relationships_parent.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/host_statkey_definitions.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/maintenanceschedules_empty.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/node_status_503.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/platform_adapters.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/platform_node_statkey_definitions.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/platform_node_statkeys.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/platform_resources_node.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/platform_resources_watchdog.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/platform_stats_latest.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/platform_stats_query.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/platform_watchdog_statkey_definitions.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/platform_watchdog_statkeys.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/properties_bulk_vcapp_services.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/recommendation_404.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/recommendations_by_id_adapter_childs.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/recommendations_by_id_vcapp.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/resource_test_llm.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/service_resource_mem.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/services_info.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/stats_query_mixed.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/stats_query_no_values.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/symptoms_ignores_id_filter.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/topn_no_groups.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/vcapp_children.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/versions_current.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/vm_properties.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/vm_relationships_all.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/vm_relationships_child.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/vm_relationships_parent.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/vm_resource_test_llm.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/vm_statkey_definitions.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/vm_statkey_definitions_full.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/vm_statkeys.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/fixtures/aria_8187/vm_statkeys_180.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/__init__.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/_live_8187.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/fixtures/aria_8187_alerts.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/fixtures/aria_8187_rightsizing.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_alert_ids_are_pasteable_and_times_readable.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_alert_notes.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_alert_recommendations.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_anomaly_count_is_total_anomalies.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_anomaly_limit_bounds_the_answer.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_aria_spec_conformance.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_aria_spec_shapes.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_aria_specific.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_cached_loader_agrees_with_the_resolver.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_capability_grader.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_cli_value_errors_are_usage_errors.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_cli_writes_guarded.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_credential_env_override.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_destructive_cli_asks_twice.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_doctor_does_not_send_you_to_doctor.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_doctor_uses_the_config_the_tools_use.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_documented_metric_keys_exist.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_empty_metrics_say_why.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_empty_vs_unrecognized.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_env_secret_obfuscation.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_fleet_rows_survive_the_container_key.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_health_degraded_is_not_down.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_health_says_what_it_observed.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_ids_must_be_uuid_shaped.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_instructions_name_targets.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_live_8187_alert_names.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_maintenance_mode.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_maintenance_schedules.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_mcp_parity.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_metrics_interval.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_paging_loop_terminates.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_platform_adapters.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_platform_node_resources.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_platform_surfaces.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_product_version_is_read_and_parseable.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_release_blockers.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_report_fields_do_not_lie.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_resource_catalog.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_resource_list_says_which_objects_stopped_reporting.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_result_envelope.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_rightsizing_live_8187.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_rightsizing_recommendation_history.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_service_health_is_not_the_badge.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_stats_n1.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_text_io_declares_encoding.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_top_consumers_value_is_the_ranking.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_vcapp_symptoms_name_their_resources.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_vcf91_fleet_spec.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_verify_ssl_false_needs_no_urllib3.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_version_gated_calls_declare_their_floor.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/test_api_escape.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/test_config.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/test_no_destructive_ops.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/test_safe_error_passthrough.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/test_session_pool.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/api_spec/vcf91_fleet_operations.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/api_spec/vcfops91_operations.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/api_spec/vrops86_operations.json +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/cli_api.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/cli_catalog.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/cli_platform.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/cli_workflow.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/config.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/doctor.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/init_wizard.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/__init__.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/__main__.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/mcp_server/tools/__init__.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/notify/__init__.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/notify/audit.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/__init__.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/_collection.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/_ids.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/_paging.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/alert_notes.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/alert_recommendations.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/alerts.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/anomaly.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/api_escape.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/capacity.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/catalog.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/fleet.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/gate_measures.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/health.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/maintenance.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/platform.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/promql.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/reports.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/service_state.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/ops/symptom_resources.py +0 -0
- {vmware_aria-2.4.0 → vmware_aria-2.4.2}/vmware_aria/policy_environment.py +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
|
|
3
3
|
"name": "vmware-aria",
|
|
4
4
|
"displayName": "VMware Aria",
|
|
5
|
-
"version": "2.4.
|
|
5
|
+
"version": "2.4.2",
|
|
6
6
|
"description": "VMware Aria Operations: metrics, alerts, capacity, anomaly detection — 46 MCP tools.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Wei Zhou",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vmware-aria
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.2
|
|
4
4
|
Summary: VMware Aria Operations (vRealize Operations) monitoring, alerting, and capacity planning
|
|
5
5
|
Project-URL: Homepage, https://github.com/vmware-skills/VMware-Aria
|
|
6
6
|
Project-URL: Repository, https://github.com/vmware-skills/VMware-Aria
|
|
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
15
15
|
Classifier: Topic :: System :: Monitoring
|
|
16
16
|
Requires-Python: >=3.10
|
|
17
17
|
Requires-Dist: httpx<1.0,>=0.27
|
|
18
|
-
Requires-Dist: mcp[cli]<2.0,>=1.
|
|
18
|
+
Requires-Dist: mcp[cli]<2.0,>=1.30
|
|
19
19
|
Requires-Dist: python-dotenv<2.0,>=1.0
|
|
20
20
|
Requires-Dist: pyyaml<7.0,>=6.0
|
|
21
21
|
Requires-Dist: rich<15.0,>=13.0
|
|
@@ -26,6 +26,8 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
<!-- mcp-name: io.github.vmware-skills/vmware-aria -->
|
|
27
27
|
# VMware Aria Operations MCP Skill
|
|
28
28
|
|
|
29
|
+
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.
|
|
30
|
+
|
|
29
31
|
> **Note**: In VCF 9.0 and later, **VMware Aria Operations** has been rebranded as **VCF Operations**. This skill works against both names — the `/suite-api/` REST endpoints are unchanged.
|
|
30
32
|
|
|
31
33
|
> **Author**: Wei Zhou, VMware by Broadcom — wei-wz.zhou@broadcom.com
|
|
@@ -240,7 +242,7 @@ VMs / Hosts / Clusters / Alerts / Capacity
|
|
|
240
242
|
- Passwords loaded from env vars or `.env` file, never from `config.yaml`
|
|
241
243
|
- Every MCP tool call and every CLI command that reaches Aria audit-logged to `~/.vmware/audit.db` (via vmware-policy); CLI write operations (alert acknowledge/cancel, alert notes, alert definition management, report generate/delete, resource maintenance start/end) also append to `~/.vmware-aria/audit.log`
|
|
242
244
|
- API responses sanitized (control chars stripped, 500-char limit) to prevent prompt injection
|
|
243
|
-
- MCP destructive writes (alert acknowledge/cancel, alert definition and report delete, maintenance start/end) take `confirm` (default `false`): without `confirm=true` they return a `blast_radius` of what would change and change nothing; `confirm=true` is refused on a blocker (e.g. a resource already in maintenance) or an unreadable field. `confirmed`
|
|
245
|
+
- MCP destructive writes (alert acknowledge/cancel, alert definition and report delete, maintenance start/end) take `confirm` (default `false`): without `confirm=true` they return a `blast_radius` of what would change and change nothing; `confirm=true` is refused on a blocker (e.g. a resource already in maintenance) or an unreadable field. The old `confirmed` alias was removed in 2.4.2; a call that passes it is refused as an unknown argument
|
|
244
246
|
- TLS verification is on by default; for a private CA set `SSL_CERT_FILE` to a bundle with your CA (see setup guide). `verify_ssl: false` is for isolated self-signed labs only
|
|
245
247
|
|
|
246
248
|
#### Official Broadcom References
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<!-- mcp-name: io.github.vmware-skills/vmware-aria -->
|
|
2
2
|
# VMware Aria Operations MCP Skill
|
|
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)。
|
|
@@ -200,7 +202,7 @@ Token 为 6 小时滑动有效期(每次调用自动延长,官方规范行
|
|
|
200
202
|
- 密码仅从环境变量或 `.env` 文件加载,不存入 `config.yaml`
|
|
201
203
|
- 每次 MCP 工具调用和每条访问 Aria 的 CLI 命令记录审计日志至 `~/.vmware/audit.db`(经 vmware-policy);CLI 写操作(告警确认/取消、告警备注、告警定义管理、报表生成/删除、资源维护开始/结束)另写 `~/.vmware-aria/audit.log`
|
|
202
204
|
- API 响应经过净化处理(去除控制字符,截断至 500 字符),防止提示注入攻击
|
|
203
|
-
- MCP 的破坏性写操作(告警确认/取消、删除告警定义和报表、开始/结束维护)带 `confirm` 参数(默认 `false`):不传 `confirm=true` 时只返回将改变什么的 `blast_radius`,不做任何修改;遇到阻断项(如资源已在维护中)或有字段读不到时,`confirm=true`
|
|
205
|
+
- MCP 的破坏性写操作(告警确认/取消、删除告警定义和报表、开始/结束维护)带 `confirm` 参数(默认 `false`):不传 `confirm=true` 时只返回将改变什么的 `blast_radius`,不做任何修改;遇到阻断项(如资源已在维护中)或有字段读不到时,`confirm=true` 会被拒绝。旧的 `confirmed` 别名已在 2.4.2 移除,仍传它的调用会被当作未知参数拒绝
|
|
204
206
|
- 默认开启 TLS 校验;私有 CA 请把 `SSL_CERT_FILE` 指向包含你 CA 的证书包(见 setup guide)。`verify_ssl: false` 仅用于隔离的自签名实验环境
|
|
205
207
|
|
|
206
208
|
<!-- usage: remote-and-exposure -->
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<!-- mcp-name: io.github.vmware-skills/vmware-aria -->
|
|
2
2
|
# VMware Aria Operations MCP Skill
|
|
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
|
> **Note**: In VCF 9.0 and later, **VMware Aria Operations** has been rebranded as **VCF Operations**. This skill works against both names — the `/suite-api/` REST endpoints are unchanged.
|
|
5
7
|
|
|
6
8
|
> **Author**: Wei Zhou, VMware by Broadcom — wei-wz.zhou@broadcom.com
|
|
@@ -215,7 +217,7 @@ VMs / Hosts / Clusters / Alerts / Capacity
|
|
|
215
217
|
- Passwords loaded from env vars or `.env` file, never from `config.yaml`
|
|
216
218
|
- Every MCP tool call and every CLI command that reaches Aria audit-logged to `~/.vmware/audit.db` (via vmware-policy); CLI write operations (alert acknowledge/cancel, alert notes, alert definition management, report generate/delete, resource maintenance start/end) also append to `~/.vmware-aria/audit.log`
|
|
217
219
|
- API responses sanitized (control chars stripped, 500-char limit) to prevent prompt injection
|
|
218
|
-
- MCP destructive writes (alert acknowledge/cancel, alert definition and report delete, maintenance start/end) take `confirm` (default `false`): without `confirm=true` they return a `blast_radius` of what would change and change nothing; `confirm=true` is refused on a blocker (e.g. a resource already in maintenance) or an unreadable field. `confirmed`
|
|
220
|
+
- MCP destructive writes (alert acknowledge/cancel, alert definition and report delete, maintenance start/end) take `confirm` (default `false`): without `confirm=true` they return a `blast_radius` of what would change and change nothing; `confirm=true` is refused on a blocker (e.g. a resource already in maintenance) or an unreadable field. The old `confirmed` alias was removed in 2.4.2; a call that passes it is refused as an unknown argument
|
|
219
221
|
- TLS verification is on by default; for a private CA set `SSL_CERT_FILE` to a bundle with your CA (see setup guide). `verify_ssl: false` is for isolated self-signed labs only
|
|
220
222
|
|
|
221
223
|
#### Official Broadcom References
|
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
## v2.4.2 — p95 in metric summaries; the `confirmed` alias is gone; error hints fit the error
|
|
2
|
+
|
|
3
|
+
* **Breaking for callers still sending `confirmed`:** the deprecated alias on `acknowledge_alert`, `cancel_alert`,
|
|
4
|
+
`delete_alert_definition`, `delete_report`, `start_resource_maintenance` and `end_resource_maintenance` is removed. A call that passes it is refused
|
|
5
|
+
as an unknown argument ("Extra inputs are not permitted") and changes nothing; pass `confirm=true`. A call without
|
|
6
|
+
`confirm` previews, as before.
|
|
7
|
+
* **`get_resource_metrics(summary=true)` adds `p95`** per series (nearest rank), with `p95_unavailable` saying why
|
|
8
|
+
when the window holds fewer than 20 numeric points ("widen the window or use a finer interval"). Issue #22.
|
|
9
|
+
Live on 8.18.7: 288 five-minute points, `cpu|demandmhz` p95 50.2.
|
|
10
|
+
* **Error hints fit the error.** A malformed id, a 400/404/409/422 the message already explains (including the
|
|
11
|
+
9.0+-only fleet / findings / PromQL endpoints on 8.x) and a missing password env var now say "The error message
|
|
12
|
+
says what to change; connectivity is not the problem" instead of sending the agent to `doctor`, which would
|
|
13
|
+
report green. Login failures (401/403), 5xx, transport, TLS and unparseable responses keep the doctor hint.
|
|
14
|
+
A TLS connection that ends early now points to service/proxy TLS logs instead of certificate trust or host/port checks.
|
|
15
|
+
* **`investigate_alert` on "Objects are not receiving data from adapter instance"**: `next_step` is now
|
|
16
|
+
`list_resources(resource_kind=all, collection_status=NO_DATA_RECEIVING)` with the adapter kind to keep, which
|
|
17
|
+
names the objects that stopped reporting, instead of "no vmware-monitor tool covers this kind".
|
|
18
|
+
* Setup guide: "Behind an MCP gateway" (identity per caller, read-only kept on the backends, tool-list size,
|
|
19
|
+
timeouts, session expiry). AIops#45.
|
|
20
|
+
|
|
21
|
+
## v2.4.1 — a target-limited role can use this skill
|
|
22
|
+
|
|
23
|
+
* **Roles (HLD §18): the target resolver raised on every call.** It read a `name` field that this skill's target
|
|
24
|
+
config does not have, so every call by a token whose role lists targets was refused as "cannot be resolved".
|
|
25
|
+
Tokens with the built-in `admin` / `reader` roles, stdio and the CLI were not affected. Found on Log-Insight
|
|
26
|
+
(same code in five skills); the new test calls the resolver on a real loaded config.
|
|
27
|
+
|
|
28
|
+
* Requires `mcp` ≥ 1.30, a security floor (GHSA-84m7-p3x7-pcfv).
|
|
29
|
+
|
|
1
30
|
## v2.4.0 — roles for network callers (HLD §18)
|
|
2
31
|
|
|
3
32
|
* Declares the role metadata vmware-policy ≥ 1.24.0 needs to apply **roles** to this server over HTTPS
|
|
@@ -1756,4 +1785,4 @@ Initial release of `vmware-aria` — VMware Aria Operations AI monitoring skill.
|
|
|
1756
1785
|
### Compatibility
|
|
1757
1786
|
- Python 3.10+
|
|
1758
1787
|
- Aria Operations 8.x (vRealize Operations 8.x)
|
|
1759
|
-
- Suite API v2 (`/suite-api/api/`)
|
|
1788
|
+
- Suite API v2 (`/suite-api/api/`)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vmware-aria"
|
|
7
|
-
version = "2.4.
|
|
7
|
+
version = "2.4.2"
|
|
8
8
|
description = "VMware Aria Operations (vRealize Operations) monitoring, alerting, and capacity planning"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -23,7 +23,7 @@ dependencies = [
|
|
|
23
23
|
"rich>=13.0,<15.0",
|
|
24
24
|
"pyyaml>=6.0,<7.0",
|
|
25
25
|
"python-dotenv>=1.0,<2.0",
|
|
26
|
-
"mcp[cli]>=1.
|
|
26
|
+
"mcp[cli]>=1.30,<2.0",
|
|
27
27
|
"vmware-policy>=1.22.0,<2.0",
|
|
28
28
|
]
|
|
29
29
|
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"url": "https://github.com/vmware-skills/VMware-Aria",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.4.
|
|
10
|
+
"version": "2.4.2",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "pypi",
|
|
14
14
|
"identifier": "vmware-aria",
|
|
15
|
-
"version": "2.4.
|
|
15
|
+
"version": "2.4.2",
|
|
16
16
|
"runtimeHint": "uvx",
|
|
17
17
|
"packageArguments": [
|
|
18
18
|
{
|
|
@@ -22,6 +22,8 @@ compatibility: >
|
|
|
22
22
|
|
|
23
23
|
# VMware Aria Operations
|
|
24
24
|
|
|
25
|
+
> Self-test: [guide](https://github.com/vmware-skills/marketplace/blob/main/MODEL_FIT_SELF_TEST.md).
|
|
26
|
+
|
|
25
27
|
> **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 "Aria" are trademarks of Broadcom. Source code is publicly auditable at [github.com/vmware-skills/VMware-Aria](https://github.com/vmware-skills/VMware-Aria) under the MIT license.
|
|
26
28
|
|
|
27
29
|
VMware Aria Operations (vRealize Operations 8.x, VCF Operations 9.x) AI-assisted monitoring — 46 MCP tools, by category below.
|
|
@@ -49,7 +51,7 @@ VMware Aria Operations (vRealize Operations 8.x, VCF Operations 9.x) AI-assisted
|
|
|
49
51
|
## Quick Install
|
|
50
52
|
|
|
51
53
|
```bash
|
|
52
|
-
uv tool install vmware-aria==2.4.
|
|
54
|
+
uv tool install vmware-aria==2.4.2
|
|
53
55
|
vmware-aria init # guided setup: writes config + .env (chmod 600, password grep-safe), then verifies
|
|
54
56
|
vmware-aria doctor
|
|
55
57
|
```
|
|
@@ -147,7 +149,7 @@ All MCP tools accept an optional `target`. The six destructive writes take `conf
|
|
|
147
149
|
|----------|------|:----:|-------------|
|
|
148
150
|
| Resource | `list_resources` | Read | List VMs, hosts, clusters by resource kind (or `all`); `collection_status` finds objects not receiving data |
|
|
149
151
|
| | `get_resource` | Read | Get resource details with health, risk, efficiency badges |
|
|
150
|
-
| | `get_resource_metrics` | Read | Time-series stats; `interval_type=DAYS` for long windows; `summary=true` gives min/max/avg/latest; `missing` explains absent |
|
|
152
|
+
| | `get_resource_metrics` | Read | Time-series stats; `interval_type=DAYS` for long windows; `summary=true` gives min/max/avg/p95/latest; `missing` explains absent |
|
|
151
153
|
| | `get_resource_health` | Read | Badge scores; service objects add `service.available` (a badge is not service state) |
|
|
152
154
|
| | `get_top_consumers` | Read | Rank by last-hour average `value` (`latest_value` = newest point) |
|
|
153
155
|
| | `list_metric_keys` | Read | Keys a resource reports with name/unit and `definition`, or a kind's defined keys — look up before querying |
|
|
@@ -306,7 +308,7 @@ Set `VMWARE_ARIA_<TARGET_NAME_UPPER>_PASSWORD` (hyphens become underscores; targ
|
|
|
306
308
|
|
|
307
309
|
### `invalid peer certificate: UnknownIssuer` when running uvx (corporate TLS proxy)
|
|
308
310
|
|
|
309
|
-
`uvx` re-resolves from PyPI on every launch, and a TLS-intercepting proxy breaks that. Run `vmware-aria mcp` after `uv tool install vmware-aria==2.4.
|
|
311
|
+
`uvx` re-resolves from PyPI on every launch, and a TLS-intercepting proxy breaks that. Run `vmware-aria mcp` after `uv tool install vmware-aria==2.4.2` (no network on launch), or set `UV_NATIVE_TLS=true` to use the system cert store.
|
|
310
312
|
|
|
311
313
|
## Audit & Safety
|
|
312
314
|
|
|
@@ -40,7 +40,10 @@ the whole sequence server-side and returns:
|
|
|
40
40
|
`resource_id`), plus `resource_name`, `resource_kind`, and a `confirmed`
|
|
41
41
|
flag. Every key is always present; unresolved values are explicit `null`.
|
|
42
42
|
- `next_step` — the exact vmware-monitor tool and argument to call next, or
|
|
43
|
-
`null` when there is nothing confirmed to hand off.
|
|
43
|
+
`null` when there is nothing confirmed to hand off. For an "Objects are not
|
|
44
|
+
receiving data from adapter instance" alert it is vmware-aria's own
|
|
45
|
+
`list_resources` with `collection_status=NO_DATA_RECEIVING`, which names the
|
|
46
|
+
objects that stopped reporting.
|
|
44
47
|
- `warnings` — why anything above is incomplete; empty on success.
|
|
45
48
|
|
|
46
49
|
A resource that cannot be resolved degrades to a warning plus explicit nulls
|
|
@@ -8,7 +8,7 @@ Each operation is classified by autonomy level per the Enterprise Harness Engine
|
|
|
8
8
|
|:-:|---|---|---|
|
|
9
9
|
| **L1** | Read-only, raw data | Always auto-run | `list_resources`, `get_resource`, `get_resource_metrics`, `list_metric_keys`, `get_resource_properties`, `get_resource_relationships`, `list_alerts`, `get_alert`, `list_alert_definitions`, `list_alert_notes`, `list_maintenance_schedules`, `get_aria_node_resources`, `list_adapters`, `search_api_operations`, `get_api_path`, capacity / badge queries |
|
|
10
10
|
| **L2** | Read + analysis / recommendation | Always auto-run | `investigate_alert` (alert → confirmed affected resource), `get_alert_recommendations` (alert → definition state → prioritized recommendations), anomaly counts, top-N consumer ranking, capacity trend forecasting, rightsizing recommendations |
|
|
11
|
-
| **L3** | Single write — user must approve | Only after explicit confirmation | `acknowledge_alert` (via takeownership action), `cancel_alert`, `create_alert_definition`, `set_alert_definition_state`, `delete_alert_definition`, `generate_report`, `delete_report`, `start_resource_maintenance`, `end_resource_maintenance`, `add_alert_note` *(the only writes; all auditable. On MCP, `acknowledge_alert`, `cancel_alert`, `delete_alert_definition`, `delete_report`, `start_resource_maintenance` and `end_resource_maintenance` take `confirm` (default false): without `confirm=true` they return a `blast_radius` — what the call would change — and change nothing; `confirm=true` is refused when a blocker is found or a field the radius depends on could not be read. `confirmed`
|
|
11
|
+
| **L3** | Single write — user must approve | Only after explicit confirmation | `acknowledge_alert` (via takeownership action), `cancel_alert`, `create_alert_definition`, `set_alert_definition_state`, `delete_alert_definition`, `generate_report`, `delete_report`, `start_resource_maintenance`, `end_resource_maintenance`, `add_alert_note` *(the only writes; all auditable. On MCP, `acknowledge_alert`, `cancel_alert`, `delete_alert_definition`, `delete_report`, `start_resource_maintenance` and `end_resource_maintenance` take `confirm` (default false): without `confirm=true` they return a `blast_radius` — what the call would change — and change nothing; `confirm=true` is refused when a blocker is found or a field the radius depends on could not be read. The old `confirmed` alias was removed in 2.4.2; a call that passes it is refused as an unknown argument. `add_alert_note` is low risk and has no gate — a note changes neither the alert nor monitoring; the CLI still asks once)* |
|
|
12
12
|
| **L4** | Multi-step plan / apply workflow | *N/A currently* | — *(no multi-step orchestration; Aria is observe/analyze, not configure)* |
|
|
13
13
|
| **L5** | Auto-remediation from learned pattern | Pattern library only; requires `risk:low` + `reversible:true` + `repeatable:true` | *(roadmap — candidates: auto-acknowledge known-noisy alerts, auto-cancel resolved-by-event alerts)* |
|
|
14
14
|
|
|
@@ -93,7 +93,7 @@ Options:
|
|
|
93
93
|
--metrics -m TEXT Comma-separated metric keys
|
|
94
94
|
[default: cpu|usage_average,mem|usage_average]
|
|
95
95
|
--hours INT History window in hours [default: 1]
|
|
96
|
-
--summary Per metric n/min/max/avg/latest and change points, instead of every point
|
|
96
|
+
--summary Per metric n/min/max/avg/p95/latest and change points, instead of every point
|
|
97
97
|
--interval-type TEXT Span each point covers: MINUTES, HOURS, DAYS, WEEKS, MONTHS [default: MINUTES]
|
|
98
98
|
--interval-quantity INT
|
|
99
99
|
Units of --interval-type per point, at least 1 [default: 5]
|
|
@@ -146,10 +146,13 @@ only keys that `sanitize()` leaves unchanged and that are at most 200 characters
|
|
|
146
146
|
A missing key is not a zero. (Before this change the output was a bare object keyed by metric.)
|
|
147
147
|
|
|
148
148
|
With `--summary` (MCP `summary=true`) `mode` is `summary` and `metrics` is replaced by `summary`: per key `n`, `min`,
|
|
149
|
-
`max`, `avg`, `latest`, `first_timestamp_ms`, `latest_timestamp_ms`, `change_count`, `change_points` (each
|
|
149
|
+
`max`, `avg`, `p95`, `latest`, `first_timestamp_ms`, `latest_timestamp_ms`, `change_count`, `change_points` (each
|
|
150
150
|
`{timestamp_ms, from, to}` where the value differed from the point before — e.g. `badge|health` 100 → 25; at most 50,
|
|
151
151
|
the most recent kept, `change_points_truncated` says when more were dropped) and `non_numeric_points`. `missing` is
|
|
152
152
|
unchanged. A continuously varying metric such as CPU usage changes at almost every point, so read `change_count` there.
|
|
153
|
+
`p95` is the nearest-rank 95th percentile of the numeric points, an observed value. It is over the points as returned,
|
|
154
|
+
so with `--interval-type DAYS` it is the p95 of daily values, not of the 5-minute samples. With fewer than 20 numeric
|
|
155
|
+
points it is `null` and `p95_unavailable` says why.
|
|
153
156
|
|
|
154
157
|
### `vmware-aria resource health`
|
|
155
158
|
|
|
@@ -16,19 +16,19 @@ Complete setup and security guide for `vmware-aria`.
|
|
|
16
16
|
### Via uv (recommended)
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
uv tool install vmware-aria==2.4.
|
|
19
|
+
uv tool install vmware-aria==2.4.2
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
### Via pip
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
pip install vmware-aria==2.4.
|
|
25
|
+
pip install vmware-aria==2.4.2
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
### From source
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
git clone --branch v2.4.
|
|
31
|
+
git clone --branch v2.4.2 https://github.com/vmware-skills/VMware-Aria.git
|
|
32
32
|
cd VMware-Aria
|
|
33
33
|
pip install -e .
|
|
34
34
|
```
|
|
@@ -194,7 +194,7 @@ Add to `~/.claude.json` (or use `claude mcp add`):
|
|
|
194
194
|
|
|
195
195
|
> v1.5.15+ recommends `vmware-aria mcp`. Pre-1.5.15 used the legacy
|
|
196
196
|
> `vmware-aria-mcp` console script (still kept for backward compatibility).
|
|
197
|
-
> If using `uvx --from vmware-aria==2.4.
|
|
197
|
+
> If using `uvx --from vmware-aria==2.4.2 vmware-aria mcp` and you hit
|
|
198
198
|
> `invalid peer certificate: UnknownIssuer` behind a corporate TLS proxy,
|
|
199
199
|
> set `UV_NATIVE_TLS=true` or use the recommended form above.
|
|
200
200
|
|
|
@@ -272,6 +272,36 @@ vmware-aria mcp --transport https --host 0.0.0.0 --port 8443 \
|
|
|
272
272
|
`--expose read`, and a separate endpoint for operators).
|
|
273
273
|
- **Several people or roles on one endpoint:** run `vmware-audit roles enable` once, then give each token a role (`vmware-audit token create NAME --role reader`, or a role in `roles.yaml` naming tools and targets; vmware-policy ≥ 1.24.0). A role limits what the token may call on this endpoint; it cannot grant more than the account has. See vmware-policy's README, "Roles for network callers".
|
|
274
274
|
|
|
275
|
+
## Behind an MCP gateway
|
|
276
|
+
|
|
277
|
+
A gateway (one MCP endpoint in front of several servers, for example vmware-monitor, vmware-aria and
|
|
278
|
+
vmware-log-insight) works with these servers as they are: each backend runs as in
|
|
279
|
+
[Serving MCP over HTTPS](#serving-mcp-over-https), and the gateway is just another client. Tool names do not
|
|
280
|
+
collide across vmware-monitor, vmware-aria and vmware-log-insight, so the gateway needs no prefixes. What to
|
|
281
|
+
decide:
|
|
282
|
+
|
|
283
|
+
- **Who the backend sees.** If the gateway calls every backend with one token of its own, every audit row says
|
|
284
|
+
`token:<gateway>` and per-caller roles stop meaning anything. To keep per-person audit and roles, have the gateway
|
|
285
|
+
**forward each caller's own `Authorization` header** to the backend. Servers on one host with the same `OPS_HOME`
|
|
286
|
+
(default `~/.vmware`) share one token file, so one token per person works on all of them. A backend session is
|
|
287
|
+
bound to the token that opened it, so the gateway must open a backend session per caller, not share one. If the gateway does
|
|
288
|
+
its own authentication instead, give it a token per backend and accept that audit identifies the gateway, not
|
|
289
|
+
the person; forward `traceparent` or `X-Request-ID` so `vmware-audit log --correlation-id ID` still ties calls to
|
|
290
|
+
one platform request.
|
|
291
|
+
- **Read-only does not depend on the gateway.** Keep the layers on each backend: a read-only platform account (the
|
|
292
|
+
real boundary), `--expose read` so write tools are never offered, and deny rules in `~/.vmware/rules.yaml`. A
|
|
293
|
+
gateway misconfiguration then cannot turn into a write.
|
|
294
|
+
- **Tool list size is the main cost, not the extra hop.** The hop adds milliseconds; platform calls take hundreds
|
|
295
|
+
of milliseconds to seconds. But clients put every offered tool's schema into the model's context on every turn.
|
|
296
|
+
Even with `--expose read`, the schemas of vmware-monitor, vmware-aria and vmware-log-insight together come to
|
|
297
|
+
about 30,000 tokens or more. Offer the gateway's clients a curated subset, or group
|
|
298
|
+
tools per task, rather than passing all of them through.
|
|
299
|
+
- **Timeouts and sessions.** Set the gateway's per-call timeout above the longest call you expect: a call can wait
|
|
300
|
+
up to 300 s for a free session to a busy target. A backend MCP session expires after 30 minutes idle; the gateway
|
|
301
|
+
must start a new session when the backend answers 404 for an old one, as the MCP specification requires.
|
|
302
|
+
- **Scaling.** Run one backend endpoint per privilege level, not one per caller. Add sessions per target with
|
|
303
|
+
`VMWARE_MCP_POOL_SIZE` before adding processes. Point the gateway's health checks at `GET /healthz`.
|
|
304
|
+
|
|
275
305
|
## Docker Deployment
|
|
276
306
|
|
|
277
307
|
### Build and run
|
{vmware_aria-2.4.0 → vmware_aria-2.4.2}/tests/eval/regression/test_a_9x_only_404_is_not_a_bad_id.py
RENAMED
|
@@ -41,7 +41,9 @@ def test_404_on_an_8x_appliance_names_the_version_and_clears_the_id(monkeypatch)
|
|
|
41
41
|
|
|
42
42
|
msg = str(exc.value)
|
|
43
43
|
assert "8.6.4" in msg and "9.0" in msg
|
|
44
|
-
|
|
44
|
+
# Pinned to the sentence vmware-policy kept when 1.24.3 dropped "the id you
|
|
45
|
+
# passed" (these tools take no id), so the test holds on either side.
|
|
46
|
+
assert "the endpoint does not exist on this version" in msg
|
|
45
47
|
assert "copy an exact UUID" not in msg, "the misleading remedy is still being sent"
|
|
46
48
|
|
|
47
49
|
|
|
@@ -162,3 +162,63 @@ def test_mcp_summary_option(monkeypatch):
|
|
|
162
162
|
|
|
163
163
|
assert "error" not in result, result
|
|
164
164
|
assert result["summary"]["badge|health"]["latest"] == 25.0
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
# Aria#22 (from AIops#45): p95 in the summary, from the points already fetched.
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
@pytest.mark.unit
|
|
171
|
+
def test_summary_gives_p95_by_nearest_rank():
|
|
172
|
+
from vmware_aria.ops.metric_summary import summarize_series
|
|
173
|
+
|
|
174
|
+
# 1..100: the 95th of 100 sorted values is 95, an observed value, not an interpolation.
|
|
175
|
+
summary = summarize_series(_series([float(v) for v in reversed(range(1, 101))]))
|
|
176
|
+
|
|
177
|
+
assert summary["p95"] == 95.0
|
|
178
|
+
assert summary["p95_unavailable"] is None
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@pytest.mark.unit
|
|
182
|
+
def test_p95_needs_enough_points_and_says_why_when_it_has_too_few():
|
|
183
|
+
from vmware_aria.ops import metric_summary
|
|
184
|
+
|
|
185
|
+
enough = metric_summary.summarize_series(_series([float(v) for v in range(metric_summary.MIN_POINTS_FOR_P95)]))
|
|
186
|
+
too_few = metric_summary.summarize_series(_series([float(v) for v in range(metric_summary.MIN_POINTS_FOR_P95 - 1)]))
|
|
187
|
+
|
|
188
|
+
assert enough["p95"] is not None
|
|
189
|
+
assert too_few["p95"] is None
|
|
190
|
+
assert str(metric_summary.MIN_POINTS_FOR_P95) in too_few["p95_unavailable"]
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@pytest.mark.unit
|
|
194
|
+
def test_p95_of_no_points_is_unknown_not_zero():
|
|
195
|
+
from vmware_aria.ops.metric_summary import summarize_series
|
|
196
|
+
|
|
197
|
+
summary = summarize_series([{"timestamp_ms": T0, "value": None}])
|
|
198
|
+
|
|
199
|
+
assert summary["p95"] is None
|
|
200
|
+
assert summary["p95_unavailable"]
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@pytest.mark.unit
|
|
204
|
+
def test_p95_ignores_points_that_are_not_numbers():
|
|
205
|
+
from vmware_aria.ops import metric_summary
|
|
206
|
+
|
|
207
|
+
# 20 numbers 1..20 and 30 non-numeric points: p95 is rank ceil(0.95 * 20) = 19 of the
|
|
208
|
+
# numbers alone. Counting the 30 would move it.
|
|
209
|
+
points = _series([float(v) for v in range(1, 21)]) + [{"timestamp_ms": T0 + 99 * STEP, "value": None}] * 30
|
|
210
|
+
summary = metric_summary.summarize_series(points)
|
|
211
|
+
|
|
212
|
+
assert summary["n"] == 20
|
|
213
|
+
assert summary["p95"] == 19.0
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@pytest.mark.unit
|
|
217
|
+
def test_get_resource_metrics_summary_carries_p95():
|
|
218
|
+
from vmware_aria.ops.resources import get_resource_metrics
|
|
219
|
+
|
|
220
|
+
client = MagicMock()
|
|
221
|
+
client.post.return_value = _stats_body({"cpu|usage_average": [float(v) for v in range(1, 101)]})
|
|
222
|
+
result = get_resource_metrics(client, RID, ["cpu|usage_average"], summary=True)
|
|
223
|
+
|
|
224
|
+
assert result["summary"]["cpu|usage_average"]["p95"] == 95.0
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""An error about the request must not send the model to check connectivity.
|
|
2
|
+
|
|
3
|
+
2026-10-24 conversation round: a non-UUID alert_id, and a 404 that the error
|
|
4
|
+
text itself explained as "this endpoint needs VCF Operations 9.0+", both came
|
|
5
|
+
back with "Run 'vmware-aria doctor' to verify connectivity." Doctor reports
|
|
6
|
+
green for both, so the hint pointed at the one thing that was not wrong.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import json
|
|
13
|
+
import ssl
|
|
14
|
+
|
|
15
|
+
import pytest
|
|
16
|
+
|
|
17
|
+
from vmware_aria.config import ConfigError
|
|
18
|
+
from vmware_aria.connection import AriaApiError
|
|
19
|
+
from vmware_aria.mcp_server import server
|
|
20
|
+
from vmware_aria.mcp_server._shared import _DOCTOR_HINT, _FIX_IN_MESSAGE_HINT, _hint_for
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.mark.parametrize("status", [400, 404, 409, 422])
|
|
24
|
+
def test_request_statuses_say_the_message_has_the_fix(status: int) -> None:
|
|
25
|
+
assert _hint_for(AriaApiError("x", status_code=status)) == _FIX_IN_MESSAGE_HINT
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@pytest.mark.parametrize("status", [None, 401, 403, 500, 503])
|
|
29
|
+
def test_login_server_and_transport_failures_keep_doctor(status) -> None:
|
|
30
|
+
assert _hint_for(AriaApiError("x", status_code=status)) == _DOCTOR_HINT
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@pytest.mark.parametrize("exc", [ValueError("alert_id must be a UUID"), ConfigError("set VMWARE_ARIA_X_PASSWORD")])
|
|
34
|
+
def test_authored_request_errors_say_the_message_has_the_fix(exc: Exception) -> None:
|
|
35
|
+
assert _hint_for(exc) == _FIX_IN_MESSAGE_HINT
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@pytest.mark.parametrize(
|
|
39
|
+
"exc",
|
|
40
|
+
[KeyError("resourceId"), ssl.SSLError("bad cert"), json.JSONDecodeError("Expecting value", "<html>", 0), UnicodeDecodeError("utf-8", b"\xff", 0, 1, "x"), RuntimeError("boom")],
|
|
41
|
+
)
|
|
42
|
+
def test_errors_this_skill_did_not_write_keep_doctor(exc: Exception) -> None:
|
|
43
|
+
assert _hint_for(exc) == _DOCTOR_HINT
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_a_malformed_alert_id_through_the_mcp_layer(monkeypatch) -> None:
|
|
47
|
+
monkeypatch.setattr(server, "_get_connection", lambda target=None: object())
|
|
48
|
+
result = asyncio.run(server.mcp.call_tool("investigate_alert", {"alert_id": "e1fdab74-"}))
|
|
49
|
+
content = result[0] if isinstance(result, tuple) else result
|
|
50
|
+
payload = json.loads(content[0].text)
|
|
51
|
+
assert "8-4-4-4-12" in payload["error"]
|
|
52
|
+
assert payload["hint"] == _FIX_IN_MESSAGE_HINT
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
alert, a resource already in / not in maintenance) or a field the radius
|
|
10
10
|
depends on could not be read.
|
|
11
11
|
|
|
12
|
-
``confirmed``
|
|
12
|
+
The deprecated ``confirmed`` alias was removed (2.4.2): a call that still
|
|
13
|
+
passes it is refused as an unknown argument and writes nothing.
|
|
13
14
|
"""
|
|
14
15
|
|
|
15
16
|
from __future__ import annotations
|
|
@@ -177,36 +178,40 @@ def test_confirm_writes_once_and_returns_the_blast_radius(aria, tool):
|
|
|
177
178
|
assert out["blast_radius"]["unmeasured"] == []
|
|
178
179
|
|
|
179
180
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
181
|
+
def _protocol_call(tool: str, **kw: Any):
|
|
182
|
+
"""Call through the MCP layer, where the argument model refuses unknown names."""
|
|
183
|
+
first_arg = {"acknowledge_alert": "alert_id", "cancel_alert": "alert_id",
|
|
184
|
+
"delete_alert_definition": "definition_id", "delete_report": "report_id",
|
|
185
|
+
"start_resource_maintenance": "resource_id",
|
|
186
|
+
"end_resource_maintenance": "resource_id"}[tool]
|
|
187
|
+
first = {"alert_id": AID, "definition_id": DEF, "report_id": REPORT, "resource_id": RID}
|
|
188
|
+
args = {first_arg: first[first_arg], **kw}
|
|
189
|
+
if tool == "start_resource_maintenance":
|
|
190
|
+
args = {"duration_minutes": 30, **args}
|
|
191
|
+
return asyncio.run(server.mcp.call_tool(tool, args))
|
|
186
192
|
|
|
187
193
|
|
|
188
194
|
@pytest.mark.parametrize("tool", GATED)
|
|
189
|
-
def
|
|
195
|
+
def test_the_removed_confirmed_alias_is_refused_and_writes_nothing(aria, tool):
|
|
190
196
|
client = _ready(aria, tool)
|
|
191
|
-
|
|
192
|
-
|
|
197
|
+
with pytest.raises(Exception, match="confirmed"):
|
|
198
|
+
_protocol_call(tool, confirmed=True)
|
|
193
199
|
assert client.writes == []
|
|
194
|
-
assert "deprecated" in out
|
|
195
200
|
|
|
196
201
|
|
|
197
202
|
@pytest.mark.parametrize("tool", GATED)
|
|
198
|
-
def
|
|
203
|
+
def test_no_deprecation_note_any_more(aria, tool):
|
|
199
204
|
_ready(aria, tool)
|
|
200
205
|
assert "deprecated" not in _call(tool)
|
|
206
|
+
assert "deprecated" not in _call(tool, confirm=True)
|
|
201
207
|
|
|
202
208
|
|
|
203
209
|
@pytest.mark.parametrize("tool", GATED)
|
|
204
|
-
def
|
|
210
|
+
def test_schema_defaults_confirm_false_and_has_no_alias(tool):
|
|
205
211
|
t = next(x for x in asyncio.run(server.mcp.list_tools()) if x.name == tool)
|
|
206
212
|
props = t.inputSchema["properties"]
|
|
207
213
|
assert props["confirm"]["default"] is False
|
|
208
|
-
assert
|
|
209
|
-
assert "Deprecated alias for confirm" in props["confirmed"]["description"]
|
|
214
|
+
assert "confirmed" not in props
|
|
210
215
|
assert "confirm" not in t.inputSchema.get("required", [])
|
|
211
216
|
|
|
212
217
|
|
|
@@ -115,6 +115,9 @@ def test_tls_error_hint_suggests_verify_ssl():
|
|
|
115
115
|
|
|
116
116
|
assert _is_tls_verify_error(Exception("certificate verify failed: self signed"))
|
|
117
117
|
assert not _is_tls_verify_error(Exception("Connection refused"))
|
|
118
|
+
assert not _is_tls_verify_error(
|
|
119
|
+
Exception("[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol")
|
|
120
|
+
)
|
|
118
121
|
|
|
119
122
|
|
|
120
123
|
def test_tls_error_hint_offers_trusting_the_ca_before_disabling_verification():
|
|
@@ -133,3 +136,14 @@ def test_tls_error_hint_offers_trusting_the_ca_before_disabling_verification():
|
|
|
133
136
|
assert "verify_ssl: false" in hint
|
|
134
137
|
assert hint.index("SSL_CERT_FILE") < hint.index("verify_ssl: false")
|
|
135
138
|
assert "lab" in hint[hint.index("SSL_CERT_FILE"):]
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def test_tls_early_eof_hint_points_to_service_or_proxy_not_ca():
|
|
142
|
+
from vmware_aria.connection import _transport_hint
|
|
143
|
+
|
|
144
|
+
hint = _transport_hint(Exception(
|
|
145
|
+
"[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol"
|
|
146
|
+
))
|
|
147
|
+
assert "TLS connection closed unexpectedly" in hint
|
|
148
|
+
assert "Aria Operations service" in hint
|
|
149
|
+
assert "SSL_CERT_FILE" not in hint
|
|
@@ -200,3 +200,28 @@ def test_aria_enum_values_are_passed_through_verbatim():
|
|
|
200
200
|
assert result["alert"]["status"] == "ACTIVE"
|
|
201
201
|
assert result["alert"]["alert_impact"] == "RISK"
|
|
202
202
|
assert result["alert"]["control_state"] == "OPEN"
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def test_no_data_alert_hands_off_to_the_objects_that_stopped_reporting():
|
|
206
|
+
"""The alert's resource is the adapter instance; the user asks which objects stopped.
|
|
207
|
+
|
|
208
|
+
2026-10-24 conversation round: next_step said "no vmware-monitor tool covers
|
|
209
|
+
VMWARE_INFRA_HEALTH_INSTANCE", which was true and left the model to find
|
|
210
|
+
list_resources(collection_status=...) on its own.
|
|
211
|
+
"""
|
|
212
|
+
alert = _alert_payload()
|
|
213
|
+
alert["alertDefinitionId"] = (
|
|
214
|
+
"AlertDefinition-vCenter Operations Adapter-AdapterChildsNoDataReceivingAlert"
|
|
215
|
+
)
|
|
216
|
+
resource = _resource_payload(kind="VMWARE_INFRA_HEALTH_INSTANCE", name="Infrastructure Health Adapter")
|
|
217
|
+
resource["resourceKey"]["adapterKindKey"] = "VMWARE_INFRA_HEALTH"
|
|
218
|
+
step = investigate_alert(_client(alert=alert, resource=resource), ALERT_ID)["next_step"]
|
|
219
|
+
assert step["skill"] == "vmware-aria" and step["tool"] == "list_resources"
|
|
220
|
+
assert step["args"] == {"resource_kind": "all", "collection_status": "NO_DATA_RECEIVING"}
|
|
221
|
+
assert "VMWARE_INFRA_HEALTH" in step["note"]
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def test_other_alerts_on_an_adapter_instance_keep_the_generic_handoff():
|
|
225
|
+
resource = _resource_payload(kind="VMWARE_INFRA_HEALTH_INSTANCE", name="Infrastructure Health Adapter")
|
|
226
|
+
step = investigate_alert(_client(resource=resource), ALERT_ID)["next_step"]
|
|
227
|
+
assert step["skill"] == "vmware-monitor" and step["tool"] is None
|
|
@@ -53,3 +53,30 @@ def test_the_resolver_uses_the_config_the_connection_manager_holds(monkeypatch):
|
|
|
53
53
|
held = object()
|
|
54
54
|
monkeypatch.setattr(server, "_conn_mgr", types.SimpleNamespace(_config=held))
|
|
55
55
|
assert pr._connection_config() is held # the manager's copy, not the edited file
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.mark.unit
|
|
59
|
+
def test_the_resolver_names_a_target_from_a_real_config(monkeypatch, tmp_path):
|
|
60
|
+
"""The resolver must run against a real loaded config, not a stand-in.
|
|
61
|
+
|
|
62
|
+
It returned ``get_target_strict(...).name`` — and this skill's TargetConfig has
|
|
63
|
+
no ``name``, so it raised AttributeError on every call: a target-limited role
|
|
64
|
+
was refused everything here. No test called it with a real config (found on
|
|
65
|
+
Log-Insight, 2026-10-17; same code in five skills).
|
|
66
|
+
"""
|
|
67
|
+
from vmware_aria import policy_roles as pr
|
|
68
|
+
from vmware_aria.config import load_config
|
|
69
|
+
|
|
70
|
+
conf = tmp_path / "config.yaml"
|
|
71
|
+
conf.write_text(
|
|
72
|
+
"targets:\n lab-a:\n host: a.example\n username: u\n"
|
|
73
|
+
" lab-b:\n host: b.example\n username: u\n"
|
|
74
|
+
"default_target: lab-b\n",
|
|
75
|
+
encoding="utf-8",
|
|
76
|
+
)
|
|
77
|
+
real = load_config(conf)
|
|
78
|
+
monkeypatch.setattr(pr, "_connection_config", lambda: real)
|
|
79
|
+
assert pr._target_name(None) == "lab-b"
|
|
80
|
+
assert pr._target_name("lab-a") == "lab-a"
|
|
81
|
+
with pytest.raises(KeyError):
|
|
82
|
+
pr._target_name("no-such-target")
|