mcp-openstack-ops 3.5.8__tar.gz → 3.5.9__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.
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/PKG-INFO +52 -34
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/README.md +50 -32
- mcp_openstack_ops-3.5.9/docs/integration-validation.md +64 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/pyproject.toml +1 -1
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/connection.py +10 -2
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/functions.py +68 -213
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/prompt_template.md +38 -20
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/services/alarms.py +107 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/identity.py +63 -3
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/image.py +9 -15
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/monitoring.py +186 -113
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/network.py +140 -4
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/orchestration.py +32 -1
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/storage.py +165 -201
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/get_domains.py +11 -0
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/get_heat_stack_details.py +12 -0
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/get_identity_groups.py +11 -0
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/get_image_members.py +11 -0
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/get_network_qos_policies.py +13 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_resource_monitoring.py +7 -5
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_usage_statistics.py +7 -5
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/get_volume_backups.py +11 -0
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/get_volume_groups.py +11 -0
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/get_volume_qos.py +11 -0
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/get_volume_transfers.py +12 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_alarms.py +23 -6
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_domains.py +3 -2
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_floating_ip.py +1 -1
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_identity_groups.py +3 -2
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_metrics.py +2 -2
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_network_qos_policies.py +3 -1
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/set_routers.py +22 -0
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/set_security_groups.py +22 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_service_logs.py +2 -2
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/set_users.py +31 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_volume_backups.py +9 -5
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_volume_groups.py +7 -2
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops/tools/set_volume_types.py +22 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops.egg-info/PKG-INFO +52 -34
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops.egg-info/SOURCES.txt +20 -1
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops.egg-info/requires.txt +1 -1
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops.egg-info/scm_file_list.json +19 -0
- mcp_openstack_ops-3.5.9/src/mcp_openstack_ops.egg-info/scm_version.json +8 -0
- mcp_openstack_ops-3.5.9/tests/test_connection.py +32 -0
- mcp_openstack_ops-3.5.9/tests/test_floating_ip.py +42 -0
- mcp_openstack_ops-3.5.9/tests/test_operational_tools.py +618 -0
- mcp_openstack_ops-3.5.9/tests/test_tool_registration.py +80 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/uv.lock +8 -7
- mcp_openstack_ops-3.5.8/src/mcp_openstack_ops.egg-info/scm_version.json +0 -8
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/.env.example +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/.env.test +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/.github/FUNDING.yml +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/.github/copilot-instructions.md +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/.github/dependabot.yml +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/.github/workflows/pypi-publish.yml +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/.gitignore +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/.gitleaks.toml +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/.pre-commit-config.yaml +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/.python-version +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/Dockerfile.MCP-Server +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/Dockerfile.MCPO-Proxy +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/LICENSE +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/MANIFEST.in +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/build-mcp-server-docker-image.sh +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/build-mcpo-server-docker-image.sh +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/diagnose_openstack.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/docker-compose.yml +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/img/MCP-Workflow-of-Quickstart-Tutorial.png +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/img/screenshot-claude-desktop.png +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/img/screenshot-claude-desktop.png:Zone.Identifier +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/img/screenshot-example-cluster-status.png +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/img/screenshot-openstack-dashboard.png +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/main.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/mcp-config.json.http +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/mcp-config.json.multi-project +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/mcp-config.json.stdio +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/scripts/check_release.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/scripts/mcp-server-docker-cmd.sh +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/scripts/publish_release.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/scripts/run-mcp-inspector-local.sh +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/scripts/run-mcp-inspector-pypi.sh +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/setup.cfg +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/__init__.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/__main__.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/mcp_main.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/__init__.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/compute.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/core.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/load_balancer/__init__.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/load_balancer/amphorae.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/load_balancer/core.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/load_balancer/health_monitors.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/load_balancer/l7_policies.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/load_balancer/listeners.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/load_balancer/management.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/services/load_balancer/pools.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/__init__.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_availability_zones.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_floating_ip_pools.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_floating_ips.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_heat_stacks.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_hypervisor_details.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_image_detail_list.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_instance.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_instance_by_name.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_instance_details.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_instances_by_status.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_keypair_list.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_amphorae.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_availability_zones.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_details.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_flavors.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_health_monitors.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_l7_policies.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_l7_rules.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_list.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_listeners.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_pool_members.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_pools.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_providers.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_load_balancer_quotas.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_network_details.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_project_details.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_quota.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_role_assignments.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_routers.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_security_groups.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_server_events.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_server_groups.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_server_volumes.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_service_status.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_user_list.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_volume_list.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_volume_snapshots.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/get_volume_types.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/search_instances.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_compute_agents.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_flavor.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_floating_ip_port_forwarding.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_heat_stack.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_image.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_image_members.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_image_metadata.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_image_visibility.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_instance.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_keypair.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer_amphora.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer_availability_zone.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer_flavor.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer_health_monitor.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer_l7_policy.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer_l7_rule.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer_listener.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer_pool.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer_pool_member.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_load_balancer_quota.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_network_agents.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_network_ports.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_networks.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_project.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_quota.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_roles.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_server_backup.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_server_dump.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_server_fixed_ip.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_server_floating_ip.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_server_group.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_server_migration.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_server_network.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_server_properties.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_server_security_group.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_server_volume.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_services.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_snapshot.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_subnets.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_volume.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops/tools/set_volume_qos.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops.egg-info/dependency_links.txt +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops.egg-info/entry_points.txt +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/src/mcp_openstack_ops.egg-info/top_level.txt +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/test_compatibility.sh +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/test_project_isolation.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/tests/test_publish_release.py +0 -0
- {mcp_openstack_ops-3.5.8 → mcp_openstack_ops-3.5.9}/tests/test_release.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-openstack-ops
|
|
3
|
-
Version: 3.5.
|
|
3
|
+
Version: 3.5.9
|
|
4
4
|
Summary: OpenStack operations automation MCP server
|
|
5
5
|
Author-email: JungJungIn <call518@gmail.com>
|
|
6
6
|
Requires-Python: >=3.12
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Requires-Dist: fastmcp>=2.12.3
|
|
10
|
-
Requires-Dist: openstacksdk<=4.
|
|
10
|
+
Requires-Dist: openstacksdk<=4.22.0,>=4.1.0
|
|
11
11
|
Requires-Dist: python-dotenv>=1.1.1
|
|
12
12
|
Requires-Dist: setuptools-scm>=10.0.5
|
|
13
13
|
Requires-Dist: pre-commit>=4.6.0
|
|
@@ -43,10 +43,10 @@ Dynamic: license-file
|
|
|
43
43
|
|
|
44
44
|
- ✅ **Project-Scoped Operations**: Every tool enforces the configured `OS_PROJECT_NAME`, validating resource ownership so actions stay inside a single tenant.
|
|
45
45
|
- ✅ **Safety-Gated Writes**: Modify (`set_*`) tooling only registers when `ALLOW_MODIFY_OPERATIONS=true`, keeping default deployments read-only and auditable.
|
|
46
|
-
- ✅ **90+ Purpose-Built Tools**: Broad coverage across compute, networking, storage, images, identity, Heat, and Octavia load balancing tasks
|
|
46
|
+
- ✅ **90+ Purpose-Built Tools**: Broad coverage across compute, networking, storage, images, identity, Heat, and Octavia load balancing tasks. Project resources are scoped to the active project; cloud-wide administrative APIs remain subject to OpenStack policy.
|
|
47
47
|
- ✅ **Bulk & Filtered Actions**: Instance, volume, network, image, snapshot, and keypair managers accept comma-delimited targets or filter criteria to orchestrate bulk changes intentionally.
|
|
48
48
|
- ✅ **Post-Action Feedback & Async Guidance**: Mutating tools reuse a shared result handler that adds emoji status checks, asynchronous timing notes, and follow-up verification commands.
|
|
49
|
-
- ✅ **Monitoring & Usage Insights**: `get_service_status`, `get_resource_monitoring`, `get_usage_statistics`, and quota tools
|
|
49
|
+
- ✅ **Monitoring & Usage Insights**: `get_service_status`, `get_resource_monitoring`, `get_usage_statistics`, and quota tools report service probes, project allocations, separate quota limits, and API-backed compute allocation-hours. Live utilization and historical trends are not collected.
|
|
50
50
|
- ✅ **Unified Instance Queries**: The `get_instance` tool consolidates name, ID, status, and free-form search paths with pagination plus summary/detailed modes.
|
|
51
51
|
- ✅ **Server Insight & Audit Trail**: Dedicated tools expose server events, hypervisor details, availability zones, quotas, and resource ownership to speed diagnostics.
|
|
52
52
|
- ✅ **Load Balancer Management**: Octavia tools cover listeners, pools, members, health monitors, flavors, quotas, and amphora operations with the same safety gates.
|
|
@@ -180,6 +180,11 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
180
180
|
|
|
181
181
|
**Detailed Mapping by Category**
|
|
182
182
|
|
|
183
|
+
✅ indicates an implemented API path, subject to cloud services and policy.
|
|
184
|
+
Live-validated paths and deployment limits are listed in
|
|
185
|
+
[integration validation](docs/integration-validation.md). Also see
|
|
186
|
+
[API prerequisites and result semantics](#api-prerequisites-and-result-semantics).
|
|
187
|
+
|
|
183
188
|
### 1. 🖥️ **Compute (Nova)**
|
|
184
189
|
|
|
185
190
|
| OpenStack CLI Command | MCP Tool | Status | Notes |
|
|
@@ -244,7 +249,7 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
244
249
|
| `openstack subnet list` | `get_network_details` (includes subnets) | ✅ | Subnet information included |
|
|
245
250
|
| `openstack subnet create/delete` | `set_subnets` | ✅ | Subnet management |
|
|
246
251
|
| `openstack router list` | `get_routers` | ✅ | Router listing |
|
|
247
|
-
| `openstack router create/delete` |
|
|
252
|
+
| `openstack router create/delete` | `set_routers` | ✅ | Project-owned routers; attached interfaces are not removed automatically |
|
|
248
253
|
| `openstack floating ip list` | `get_floating_ips` | ✅ | Floating IP listing |
|
|
249
254
|
| `openstack floating ip create` | `set_floating_ip` (action="create") | ✅ | Floating IP creation |
|
|
250
255
|
| `openstack floating ip delete` | `set_floating_ip` (action="delete") | ✅ | Floating IP deletion |
|
|
@@ -258,13 +263,13 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
258
263
|
| `openstack floating ip port forwarding set` | `set_floating_ip_port_forwarding` (action="set") | ✅ | Port forwarding updates |
|
|
259
264
|
| `openstack floating ip port forwarding show` | `set_floating_ip_port_forwarding` (action="show") | ✅ | Port forwarding details |
|
|
260
265
|
| `openstack security group list` | `get_security_groups` | ✅ | Security group listing |
|
|
261
|
-
| `openstack security group create/delete` |
|
|
266
|
+
| `openstack security group create/delete` | `set_security_groups` | ✅ | Project-owned security groups |
|
|
262
267
|
| `openstack port list` | `get_network_details` (includes ports) | ✅ | Port information included |
|
|
263
268
|
| `openstack port create/delete` | `set_network_ports` | ✅ | Port management |
|
|
264
|
-
| `openstack network qos policy list` |
|
|
265
|
-
| `openstack network qos policy create` | `set_network_qos_policies` | ✅ |
|
|
269
|
+
| `openstack network qos policy list` | `get_network_qos_policies` | ✅ | Current-project policy containers |
|
|
270
|
+
| `openstack network qos policy create` | `set_network_qos_policies` | ✅ | Create/list/delete policy containers; does not create bandwidth rules |
|
|
266
271
|
| `openstack network agent list` | `get_service_status` (includes agents) | ✅ | Network agents |
|
|
267
|
-
| `openstack network agent set` | `set_network_agents` | ✅ |
|
|
272
|
+
| `openstack network agent set` | `set_network_agents` | ✅ | Enable/disable cloud-wide agents; usually admin-only |
|
|
268
273
|
|
|
269
274
|
### 3. 💾 **Storage (Cinder)**
|
|
270
275
|
|
|
@@ -275,18 +280,18 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
275
280
|
| `openstack volume create/delete` | `set_volume` | ✅ | Volume creation/deletion |
|
|
276
281
|
| `openstack volume set` | `set_volume` (action="modify") | ✅ | Volume property modification |
|
|
277
282
|
| `openstack volume type list` | `get_volume_types` | ✅ | Volume type listing |
|
|
278
|
-
| `openstack volume type create/delete` |
|
|
283
|
+
| `openstack volume type create/delete` | `set_volume_types` | ✅ | Volume type management; usually admin-only |
|
|
279
284
|
| `openstack volume snapshot list` | `get_volume_snapshots` | ✅ | Snapshot listing |
|
|
280
285
|
| `openstack volume snapshot create/delete` | `set_snapshot` | ✅ | Snapshot management |
|
|
281
|
-
| `openstack backup list` |
|
|
286
|
+
| `openstack backup list` | `get_volume_backups` | ✅ | Current-project backup listing |
|
|
282
287
|
| `openstack backup create/delete` | `set_volume_backups` | ✅ | Volume backup management |
|
|
283
|
-
| `openstack volume transfer request list` |
|
|
288
|
+
| `openstack volume transfer request list` | `get_volume_transfers` | ✅ | Request listing only; authorization keys are excluded |
|
|
284
289
|
| `openstack server volume list` | `get_server_volumes` | ✅ | Server volume listing |
|
|
285
290
|
| `openstack server add/remove volume` | `set_server_volume` | ✅ | Server volume attach/detach |
|
|
286
|
-
| `openstack volume group list` |
|
|
287
|
-
| `openstack volume group create` | `set_volume_groups` | ✅ |
|
|
288
|
-
| `openstack volume qos list` |
|
|
289
|
-
| `openstack volume qos create` | `set_volume_qos` | ✅ |
|
|
291
|
+
| `openstack volume group list` | `get_volume_groups` | ✅ | Requires Cinder generic groups (API >= 3.13) |
|
|
292
|
+
| `openstack volume group create` | `set_volume_groups` | ✅ | Create/list/show/delete; create requires group_type and volume_types |
|
|
293
|
+
| `openstack volume qos list` | `get_volume_qos` | ✅ | Cinder QoS specifications; subject to cloud policy |
|
|
294
|
+
| `openstack volume qos create` | `set_volume_qos` | ✅ | Create/list/show/set/delete specifications; no automatic type association |
|
|
290
295
|
|
|
291
296
|
### 4. 🖼️ **Image (Glance)**
|
|
292
297
|
|
|
@@ -298,8 +303,8 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
298
303
|
| `openstack image delete` | `set_image` (action="delete") | ✅ | Image deletion |
|
|
299
304
|
| `openstack image set` | `set_image` (action="update") | ✅ | Image property modification |
|
|
300
305
|
| `openstack image save` | `set_image` (action="save") | ✅ | Image download |
|
|
301
|
-
| `openstack image add project` | (
|
|
302
|
-
| `openstack image member list` |
|
|
306
|
+
| `openstack image add project` | `set_image_members` (action="add") | ✅ | Add a project to an image with shared visibility |
|
|
307
|
+
| `openstack image member list` | `get_image_members` | ✅ | Image member listing |
|
|
303
308
|
| `openstack image member create` | `set_image_members` | ✅ | Image member management |
|
|
304
309
|
| `openstack image set --property` | `set_image_metadata` | ✅ | Image metadata |
|
|
305
310
|
| `openstack image set --public/private` | `set_image_visibility` | ✅ | Image visibility setting |
|
|
@@ -310,16 +315,16 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
310
315
|
|---------------------|---------|------|------|
|
|
311
316
|
| `openstack user list` | `get_user_list` | ✅ | User listing |
|
|
312
317
|
| `openstack user show` | `get_user_list` (filtering) | ✅ | Specific user query |
|
|
313
|
-
| `openstack user create/delete` |
|
|
318
|
+
| `openstack user create/delete` | `set_users` | ✅ | Password from a server environment variable; no role grants |
|
|
314
319
|
| `openstack project list` | `get_project_details` | ✅ | Project listing |
|
|
315
320
|
| `openstack project show` | `get_project_details` (name param) | ✅ | Specific project query |
|
|
316
321
|
| `openstack project create/delete` | `set_project` | ✅ | Project management |
|
|
317
322
|
| `openstack role list` | `get_role_assignments` | ✅ | Role listing |
|
|
318
323
|
| `openstack role assignment list` | `get_role_assignments` | ✅ | Role assignment listing |
|
|
319
324
|
| `openstack role create/delete` | `set_roles` | ✅ | Role management |
|
|
320
|
-
| `openstack domain list` |
|
|
321
|
-
| `openstack domain create/delete` | `set_domains` | ✅ |
|
|
322
|
-
| `openstack group list` |
|
|
325
|
+
| `openstack domain list` | `get_domains` | ✅ | Subject to Keystone policy |
|
|
326
|
+
| `openstack domain create/delete` | `set_domains` | ✅ | Disable explicitly with update before delete |
|
|
327
|
+
| `openstack group list` | `get_identity_groups` | ✅ | Subject to Keystone policy |
|
|
323
328
|
| `openstack group create/delete` | `set_identity_groups` | ✅ | Group management |
|
|
324
329
|
| `openstack service list` | `get_service_status` | ✅ | Service listing |
|
|
325
330
|
| `openstack service create/delete` | `set_services` | ✅ | Service management |
|
|
@@ -335,10 +340,10 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
335
340
|
| `openstack stack delete` | `set_heat_stack` (action="delete") | ✅ | Stack deletion |
|
|
336
341
|
| `openstack stack update` | `set_heat_stack` (action="update") | ✅ | Stack update |
|
|
337
342
|
| `openstack stack suspend/resume` | `set_heat_stack` | ✅ | Stack suspend/resume |
|
|
338
|
-
| `openstack stack resource list` | (
|
|
339
|
-
| `openstack stack event list` | (
|
|
340
|
-
| `openstack stack template show` | (
|
|
341
|
-
| `openstack stack output list` | (
|
|
343
|
+
| `openstack stack resource list` | `get_heat_stack_details` (section="resources") | ✅ | Actual Heat resources |
|
|
344
|
+
| `openstack stack event list` | `get_heat_stack_details` (section="events") | ✅ | Actual Heat events |
|
|
345
|
+
| `openstack stack template show` | `get_heat_stack_details` (section="template") | ✅ | Original template document |
|
|
346
|
+
| `openstack stack output list` | `get_heat_stack_details` (section="outputs") | ✅ | Resolved stack outputs |
|
|
342
347
|
|
|
343
348
|
### 7. ⚖️ **Load Balancer (Octavia)**
|
|
344
349
|
|
|
@@ -438,14 +443,14 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
438
443
|
|
|
439
444
|
| OpenStack CLI Command | MCP Tool | Status | Notes |
|
|
440
445
|
|---------------------|---------|------|------|
|
|
441
|
-
| Resource monitoring | `get_resource_monitoring` | ✅ |
|
|
446
|
+
| Resource monitoring | `get_resource_monitoring` | ✅ | Project allocations, separate quotas and visible hypervisor capacity; no live utilization |
|
|
442
447
|
| Service status | `get_service_status` | ✅ | Service status query |
|
|
443
|
-
| Cluster overview | `
|
|
444
|
-
| Service
|
|
445
|
-
|
|
|
446
|
-
| Alarm management | `set_alarms` | ✅ |
|
|
448
|
+
| Cluster overview | `get_service_status` + `get_resource_monitoring` | ✅ | Service probes and current inventory |
|
|
449
|
+
| Service log metadata | `set_service_logs` | Partial | Service listing only; log retrieval is unavailable without a logging backend |
|
|
450
|
+
| Resource metadata | `set_metrics` | Partial | list/summary only; telemetry sample retrieval is unavailable |
|
|
451
|
+
| Alarm management | `set_alarms` | ✅ | Real Aodh/Gnocchi resource threshold alarms; requires services and collected metrics |
|
|
447
452
|
| Compute agents | `set_compute_agents` | ✅ | Compute agent management |
|
|
448
|
-
| Usage statistics | `get_usage_statistics` | ✅ |
|
|
453
|
+
| Usage statistics | `get_usage_statistics` | ✅ | Period compute allocation-hours plus separately labeled current snapshots |
|
|
449
454
|
|
|
450
455
|
### 9. 📏 **Usage & Quota**
|
|
451
456
|
|
|
@@ -453,12 +458,25 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
453
458
|
|---------------------|---------|------|------|
|
|
454
459
|
| `openstack quota show` | `get_quota` | ✅ | Quota query |
|
|
455
460
|
| `openstack quota set` | `set_quota` | ✅ | Quota setting |
|
|
456
|
-
| `openstack usage show` | `get_usage_statistics` | ✅ |
|
|
461
|
+
| `openstack usage show` | `get_usage_statistics` | ✅ | Current-project Nova simple tenant usage; not monetary charges |
|
|
457
462
|
| `openstack limits show` | `get_quota` (includes limits) | ✅ | Limits query |
|
|
458
|
-
| Resource
|
|
463
|
+
| Resource allocations | `get_resource_monitoring` | ✅ | Flavor allocations; not CPU load or resident memory samples |
|
|
459
464
|
|
|
460
465
|
---
|
|
461
466
|
|
|
467
|
+
### API prerequisites and result semantics
|
|
468
|
+
|
|
469
|
+
The feature table marks implemented API paths, not verification against every OpenStack deployment. The management and query paths have local mocked API tests. Selected paths also passed live tests on a single-node Kolla Ansible deployment; see [integration validation](docs/integration-validation.md) for coverage and skipped operations. A missing service, extension, required microversion, or permission is an operation failure, not an empty successful result.
|
|
470
|
+
|
|
471
|
+
- **Modification tools:** the MCP server registers `set_*` management tools only when `ALLOW_MODIFY_OPERATIONS=true`. Existing action guards also reject writes when disabled. Dedicated read-only `get_*` tools remain available. API authorization is enforced by the target cloud; agent, user, domain, type and QoS administration may require elevated OpenStack roles.
|
|
472
|
+
- **Alarms:** `set_alarms` calls the Keystone catalog's `alarming` endpoint for the configured interface/region. It supports list/create/show/delete of project alarms and creates `gnocchi_resources_threshold` alarms. Aodh, Gnocchi, the specified resource and a collected metric are required. The default metric is `cpu_util`, which is not collected by every deployment. `metric`, `resource_type`, `aggregation_method`, `granularity`, `evaluation_periods`, and `alarm_actions` can be supplied. An empty action list creates an alarm without notifications. There is no simulation fallback.
|
|
473
|
+
- **Usage:** `get_usage_statistics` calls Nova simple tenant usage for the current project. Requires Nova API microversion 2.40 or newer for complete pagination. Date bounds are UTC midnight, start inclusive and end exclusive; start must precede end. `usage_statistics.period_compute` contains paginated Nova allocation-hours, not actual CPU load, billed currency, or network/storage history. Nova accounts using VM lifetime and the latest flavor; stop/pause/resize history is not reconstructed. Existing `compute`, `network`, and `storage` fields are current snapshots, labeled by `snapshot_fields` and `snapshot_timestamp`. An unavailable period API returns failure. A failed snapshot section is reported as partial failure.
|
|
474
|
+
- **Capacity:** `get_resource_monitoring` separates flavor allocations from project quota limits and the physical totals of visible hypervisors. Missing physical totals or incomplete flavor allocations return `null`, not invented capacity or zero usage. Physical totals and project allocations have different scopes. This tool does not collect live utilization or trends.
|
|
475
|
+
- **Floating IP pools:** `total_ips` is the exact sum of visible subnet allocation ranges; `used_ips` counts visible Floating IP objects. Global `available_ips` is `null`: other projects and non-floating ports may consume addresses that are not visible to the caller.
|
|
476
|
+
- **Volume groups:** the cloud must support Cinder generic groups (microversion 3.13 or newer). Create requires an existing `group_type` and comma-delimited `volume_types`. Deletion does not delete member volumes unless `delete_volumes=true` is explicitly supplied. Async creation/deletion responses mean accepted, not finished.
|
|
477
|
+
- **Identity and images:** `set_users` reads a new user's password from the server variable named by `password_env`; never put passwords in prompts. It does not grant project roles. Disable a domain explicitly with `set_domains(action="update", enabled=false)` before deleting it. Image member modifications require an image owned by the current project, shared visibility, and appropriate Glance policy; adding a member does not automatically accept the recipient's membership.
|
|
478
|
+
- **Logs and telemetry:** `set_service_logs(action="show")` and `set_metrics(action="show")` return explicit unsupported errors. No centralized logging or telemetry sample backend is implemented. Their list/summary operations expose service or resource metadata only.
|
|
479
|
+
|
|
462
480
|
## Quick Start
|
|
463
481
|
|
|
464
482
|
> 💡 **Need an OpenStack Cluster for Testing?**
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
|
|
26
26
|
- ✅ **Project-Scoped Operations**: Every tool enforces the configured `OS_PROJECT_NAME`, validating resource ownership so actions stay inside a single tenant.
|
|
27
27
|
- ✅ **Safety-Gated Writes**: Modify (`set_*`) tooling only registers when `ALLOW_MODIFY_OPERATIONS=true`, keeping default deployments read-only and auditable.
|
|
28
|
-
- ✅ **90+ Purpose-Built Tools**: Broad coverage across compute, networking, storage, images, identity, Heat, and Octavia load balancing tasks
|
|
28
|
+
- ✅ **90+ Purpose-Built Tools**: Broad coverage across compute, networking, storage, images, identity, Heat, and Octavia load balancing tasks. Project resources are scoped to the active project; cloud-wide administrative APIs remain subject to OpenStack policy.
|
|
29
29
|
- ✅ **Bulk & Filtered Actions**: Instance, volume, network, image, snapshot, and keypair managers accept comma-delimited targets or filter criteria to orchestrate bulk changes intentionally.
|
|
30
30
|
- ✅ **Post-Action Feedback & Async Guidance**: Mutating tools reuse a shared result handler that adds emoji status checks, asynchronous timing notes, and follow-up verification commands.
|
|
31
|
-
- ✅ **Monitoring & Usage Insights**: `get_service_status`, `get_resource_monitoring`, `get_usage_statistics`, and quota tools
|
|
31
|
+
- ✅ **Monitoring & Usage Insights**: `get_service_status`, `get_resource_monitoring`, `get_usage_statistics`, and quota tools report service probes, project allocations, separate quota limits, and API-backed compute allocation-hours. Live utilization and historical trends are not collected.
|
|
32
32
|
- ✅ **Unified Instance Queries**: The `get_instance` tool consolidates name, ID, status, and free-form search paths with pagination plus summary/detailed modes.
|
|
33
33
|
- ✅ **Server Insight & Audit Trail**: Dedicated tools expose server events, hypervisor details, availability zones, quotas, and resource ownership to speed diagnostics.
|
|
34
34
|
- ✅ **Load Balancer Management**: Octavia tools cover listeners, pools, members, health monitors, flavors, quotas, and amphora operations with the same safety gates.
|
|
@@ -162,6 +162,11 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
162
162
|
|
|
163
163
|
**Detailed Mapping by Category**
|
|
164
164
|
|
|
165
|
+
✅ indicates an implemented API path, subject to cloud services and policy.
|
|
166
|
+
Live-validated paths and deployment limits are listed in
|
|
167
|
+
[integration validation](docs/integration-validation.md). Also see
|
|
168
|
+
[API prerequisites and result semantics](#api-prerequisites-and-result-semantics).
|
|
169
|
+
|
|
165
170
|
### 1. 🖥️ **Compute (Nova)**
|
|
166
171
|
|
|
167
172
|
| OpenStack CLI Command | MCP Tool | Status | Notes |
|
|
@@ -226,7 +231,7 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
226
231
|
| `openstack subnet list` | `get_network_details` (includes subnets) | ✅ | Subnet information included |
|
|
227
232
|
| `openstack subnet create/delete` | `set_subnets` | ✅ | Subnet management |
|
|
228
233
|
| `openstack router list` | `get_routers` | ✅ | Router listing |
|
|
229
|
-
| `openstack router create/delete` |
|
|
234
|
+
| `openstack router create/delete` | `set_routers` | ✅ | Project-owned routers; attached interfaces are not removed automatically |
|
|
230
235
|
| `openstack floating ip list` | `get_floating_ips` | ✅ | Floating IP listing |
|
|
231
236
|
| `openstack floating ip create` | `set_floating_ip` (action="create") | ✅ | Floating IP creation |
|
|
232
237
|
| `openstack floating ip delete` | `set_floating_ip` (action="delete") | ✅ | Floating IP deletion |
|
|
@@ -240,13 +245,13 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
240
245
|
| `openstack floating ip port forwarding set` | `set_floating_ip_port_forwarding` (action="set") | ✅ | Port forwarding updates |
|
|
241
246
|
| `openstack floating ip port forwarding show` | `set_floating_ip_port_forwarding` (action="show") | ✅ | Port forwarding details |
|
|
242
247
|
| `openstack security group list` | `get_security_groups` | ✅ | Security group listing |
|
|
243
|
-
| `openstack security group create/delete` |
|
|
248
|
+
| `openstack security group create/delete` | `set_security_groups` | ✅ | Project-owned security groups |
|
|
244
249
|
| `openstack port list` | `get_network_details` (includes ports) | ✅ | Port information included |
|
|
245
250
|
| `openstack port create/delete` | `set_network_ports` | ✅ | Port management |
|
|
246
|
-
| `openstack network qos policy list` |
|
|
247
|
-
| `openstack network qos policy create` | `set_network_qos_policies` | ✅ |
|
|
251
|
+
| `openstack network qos policy list` | `get_network_qos_policies` | ✅ | Current-project policy containers |
|
|
252
|
+
| `openstack network qos policy create` | `set_network_qos_policies` | ✅ | Create/list/delete policy containers; does not create bandwidth rules |
|
|
248
253
|
| `openstack network agent list` | `get_service_status` (includes agents) | ✅ | Network agents |
|
|
249
|
-
| `openstack network agent set` | `set_network_agents` | ✅ |
|
|
254
|
+
| `openstack network agent set` | `set_network_agents` | ✅ | Enable/disable cloud-wide agents; usually admin-only |
|
|
250
255
|
|
|
251
256
|
### 3. 💾 **Storage (Cinder)**
|
|
252
257
|
|
|
@@ -257,18 +262,18 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
257
262
|
| `openstack volume create/delete` | `set_volume` | ✅ | Volume creation/deletion |
|
|
258
263
|
| `openstack volume set` | `set_volume` (action="modify") | ✅ | Volume property modification |
|
|
259
264
|
| `openstack volume type list` | `get_volume_types` | ✅ | Volume type listing |
|
|
260
|
-
| `openstack volume type create/delete` |
|
|
265
|
+
| `openstack volume type create/delete` | `set_volume_types` | ✅ | Volume type management; usually admin-only |
|
|
261
266
|
| `openstack volume snapshot list` | `get_volume_snapshots` | ✅ | Snapshot listing |
|
|
262
267
|
| `openstack volume snapshot create/delete` | `set_snapshot` | ✅ | Snapshot management |
|
|
263
|
-
| `openstack backup list` |
|
|
268
|
+
| `openstack backup list` | `get_volume_backups` | ✅ | Current-project backup listing |
|
|
264
269
|
| `openstack backup create/delete` | `set_volume_backups` | ✅ | Volume backup management |
|
|
265
|
-
| `openstack volume transfer request list` |
|
|
270
|
+
| `openstack volume transfer request list` | `get_volume_transfers` | ✅ | Request listing only; authorization keys are excluded |
|
|
266
271
|
| `openstack server volume list` | `get_server_volumes` | ✅ | Server volume listing |
|
|
267
272
|
| `openstack server add/remove volume` | `set_server_volume` | ✅ | Server volume attach/detach |
|
|
268
|
-
| `openstack volume group list` |
|
|
269
|
-
| `openstack volume group create` | `set_volume_groups` | ✅ |
|
|
270
|
-
| `openstack volume qos list` |
|
|
271
|
-
| `openstack volume qos create` | `set_volume_qos` | ✅ |
|
|
273
|
+
| `openstack volume group list` | `get_volume_groups` | ✅ | Requires Cinder generic groups (API >= 3.13) |
|
|
274
|
+
| `openstack volume group create` | `set_volume_groups` | ✅ | Create/list/show/delete; create requires group_type and volume_types |
|
|
275
|
+
| `openstack volume qos list` | `get_volume_qos` | ✅ | Cinder QoS specifications; subject to cloud policy |
|
|
276
|
+
| `openstack volume qos create` | `set_volume_qos` | ✅ | Create/list/show/set/delete specifications; no automatic type association |
|
|
272
277
|
|
|
273
278
|
### 4. 🖼️ **Image (Glance)**
|
|
274
279
|
|
|
@@ -280,8 +285,8 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
280
285
|
| `openstack image delete` | `set_image` (action="delete") | ✅ | Image deletion |
|
|
281
286
|
| `openstack image set` | `set_image` (action="update") | ✅ | Image property modification |
|
|
282
287
|
| `openstack image save` | `set_image` (action="save") | ✅ | Image download |
|
|
283
|
-
| `openstack image add project` | (
|
|
284
|
-
| `openstack image member list` |
|
|
288
|
+
| `openstack image add project` | `set_image_members` (action="add") | ✅ | Add a project to an image with shared visibility |
|
|
289
|
+
| `openstack image member list` | `get_image_members` | ✅ | Image member listing |
|
|
285
290
|
| `openstack image member create` | `set_image_members` | ✅ | Image member management |
|
|
286
291
|
| `openstack image set --property` | `set_image_metadata` | ✅ | Image metadata |
|
|
287
292
|
| `openstack image set --public/private` | `set_image_visibility` | ✅ | Image visibility setting |
|
|
@@ -292,16 +297,16 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
292
297
|
|---------------------|---------|------|------|
|
|
293
298
|
| `openstack user list` | `get_user_list` | ✅ | User listing |
|
|
294
299
|
| `openstack user show` | `get_user_list` (filtering) | ✅ | Specific user query |
|
|
295
|
-
| `openstack user create/delete` |
|
|
300
|
+
| `openstack user create/delete` | `set_users` | ✅ | Password from a server environment variable; no role grants |
|
|
296
301
|
| `openstack project list` | `get_project_details` | ✅ | Project listing |
|
|
297
302
|
| `openstack project show` | `get_project_details` (name param) | ✅ | Specific project query |
|
|
298
303
|
| `openstack project create/delete` | `set_project` | ✅ | Project management |
|
|
299
304
|
| `openstack role list` | `get_role_assignments` | ✅ | Role listing |
|
|
300
305
|
| `openstack role assignment list` | `get_role_assignments` | ✅ | Role assignment listing |
|
|
301
306
|
| `openstack role create/delete` | `set_roles` | ✅ | Role management |
|
|
302
|
-
| `openstack domain list` |
|
|
303
|
-
| `openstack domain create/delete` | `set_domains` | ✅ |
|
|
304
|
-
| `openstack group list` |
|
|
307
|
+
| `openstack domain list` | `get_domains` | ✅ | Subject to Keystone policy |
|
|
308
|
+
| `openstack domain create/delete` | `set_domains` | ✅ | Disable explicitly with update before delete |
|
|
309
|
+
| `openstack group list` | `get_identity_groups` | ✅ | Subject to Keystone policy |
|
|
305
310
|
| `openstack group create/delete` | `set_identity_groups` | ✅ | Group management |
|
|
306
311
|
| `openstack service list` | `get_service_status` | ✅ | Service listing |
|
|
307
312
|
| `openstack service create/delete` | `set_services` | ✅ | Service management |
|
|
@@ -317,10 +322,10 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
317
322
|
| `openstack stack delete` | `set_heat_stack` (action="delete") | ✅ | Stack deletion |
|
|
318
323
|
| `openstack stack update` | `set_heat_stack` (action="update") | ✅ | Stack update |
|
|
319
324
|
| `openstack stack suspend/resume` | `set_heat_stack` | ✅ | Stack suspend/resume |
|
|
320
|
-
| `openstack stack resource list` | (
|
|
321
|
-
| `openstack stack event list` | (
|
|
322
|
-
| `openstack stack template show` | (
|
|
323
|
-
| `openstack stack output list` | (
|
|
325
|
+
| `openstack stack resource list` | `get_heat_stack_details` (section="resources") | ✅ | Actual Heat resources |
|
|
326
|
+
| `openstack stack event list` | `get_heat_stack_details` (section="events") | ✅ | Actual Heat events |
|
|
327
|
+
| `openstack stack template show` | `get_heat_stack_details` (section="template") | ✅ | Original template document |
|
|
328
|
+
| `openstack stack output list` | `get_heat_stack_details` (section="outputs") | ✅ | Resolved stack outputs |
|
|
324
329
|
|
|
325
330
|
### 7. ⚖️ **Load Balancer (Octavia)**
|
|
326
331
|
|
|
@@ -420,14 +425,14 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
420
425
|
|
|
421
426
|
| OpenStack CLI Command | MCP Tool | Status | Notes |
|
|
422
427
|
|---------------------|---------|------|------|
|
|
423
|
-
| Resource monitoring | `get_resource_monitoring` | ✅ |
|
|
428
|
+
| Resource monitoring | `get_resource_monitoring` | ✅ | Project allocations, separate quotas and visible hypervisor capacity; no live utilization |
|
|
424
429
|
| Service status | `get_service_status` | ✅ | Service status query |
|
|
425
|
-
| Cluster overview | `
|
|
426
|
-
| Service
|
|
427
|
-
|
|
|
428
|
-
| Alarm management | `set_alarms` | ✅ |
|
|
430
|
+
| Cluster overview | `get_service_status` + `get_resource_monitoring` | ✅ | Service probes and current inventory |
|
|
431
|
+
| Service log metadata | `set_service_logs` | Partial | Service listing only; log retrieval is unavailable without a logging backend |
|
|
432
|
+
| Resource metadata | `set_metrics` | Partial | list/summary only; telemetry sample retrieval is unavailable |
|
|
433
|
+
| Alarm management | `set_alarms` | ✅ | Real Aodh/Gnocchi resource threshold alarms; requires services and collected metrics |
|
|
429
434
|
| Compute agents | `set_compute_agents` | ✅ | Compute agent management |
|
|
430
|
-
| Usage statistics | `get_usage_statistics` | ✅ |
|
|
435
|
+
| Usage statistics | `get_usage_statistics` | ✅ | Period compute allocation-hours plus separately labeled current snapshots |
|
|
431
436
|
|
|
432
437
|
### 9. 📏 **Usage & Quota**
|
|
433
438
|
|
|
@@ -435,12 +440,25 @@ New consolidated `get_instance` tool replaces multiple separate tools:
|
|
|
435
440
|
|---------------------|---------|------|------|
|
|
436
441
|
| `openstack quota show` | `get_quota` | ✅ | Quota query |
|
|
437
442
|
| `openstack quota set` | `set_quota` | ✅ | Quota setting |
|
|
438
|
-
| `openstack usage show` | `get_usage_statistics` | ✅ |
|
|
443
|
+
| `openstack usage show` | `get_usage_statistics` | ✅ | Current-project Nova simple tenant usage; not monetary charges |
|
|
439
444
|
| `openstack limits show` | `get_quota` (includes limits) | ✅ | Limits query |
|
|
440
|
-
| Resource
|
|
445
|
+
| Resource allocations | `get_resource_monitoring` | ✅ | Flavor allocations; not CPU load or resident memory samples |
|
|
441
446
|
|
|
442
447
|
---
|
|
443
448
|
|
|
449
|
+
### API prerequisites and result semantics
|
|
450
|
+
|
|
451
|
+
The feature table marks implemented API paths, not verification against every OpenStack deployment. The management and query paths have local mocked API tests. Selected paths also passed live tests on a single-node Kolla Ansible deployment; see [integration validation](docs/integration-validation.md) for coverage and skipped operations. A missing service, extension, required microversion, or permission is an operation failure, not an empty successful result.
|
|
452
|
+
|
|
453
|
+
- **Modification tools:** the MCP server registers `set_*` management tools only when `ALLOW_MODIFY_OPERATIONS=true`. Existing action guards also reject writes when disabled. Dedicated read-only `get_*` tools remain available. API authorization is enforced by the target cloud; agent, user, domain, type and QoS administration may require elevated OpenStack roles.
|
|
454
|
+
- **Alarms:** `set_alarms` calls the Keystone catalog's `alarming` endpoint for the configured interface/region. It supports list/create/show/delete of project alarms and creates `gnocchi_resources_threshold` alarms. Aodh, Gnocchi, the specified resource and a collected metric are required. The default metric is `cpu_util`, which is not collected by every deployment. `metric`, `resource_type`, `aggregation_method`, `granularity`, `evaluation_periods`, and `alarm_actions` can be supplied. An empty action list creates an alarm without notifications. There is no simulation fallback.
|
|
455
|
+
- **Usage:** `get_usage_statistics` calls Nova simple tenant usage for the current project. Requires Nova API microversion 2.40 or newer for complete pagination. Date bounds are UTC midnight, start inclusive and end exclusive; start must precede end. `usage_statistics.period_compute` contains paginated Nova allocation-hours, not actual CPU load, billed currency, or network/storage history. Nova accounts using VM lifetime and the latest flavor; stop/pause/resize history is not reconstructed. Existing `compute`, `network`, and `storage` fields are current snapshots, labeled by `snapshot_fields` and `snapshot_timestamp`. An unavailable period API returns failure. A failed snapshot section is reported as partial failure.
|
|
456
|
+
- **Capacity:** `get_resource_monitoring` separates flavor allocations from project quota limits and the physical totals of visible hypervisors. Missing physical totals or incomplete flavor allocations return `null`, not invented capacity or zero usage. Physical totals and project allocations have different scopes. This tool does not collect live utilization or trends.
|
|
457
|
+
- **Floating IP pools:** `total_ips` is the exact sum of visible subnet allocation ranges; `used_ips` counts visible Floating IP objects. Global `available_ips` is `null`: other projects and non-floating ports may consume addresses that are not visible to the caller.
|
|
458
|
+
- **Volume groups:** the cloud must support Cinder generic groups (microversion 3.13 or newer). Create requires an existing `group_type` and comma-delimited `volume_types`. Deletion does not delete member volumes unless `delete_volumes=true` is explicitly supplied. Async creation/deletion responses mean accepted, not finished.
|
|
459
|
+
- **Identity and images:** `set_users` reads a new user's password from the server variable named by `password_env`; never put passwords in prompts. It does not grant project roles. Disable a domain explicitly with `set_domains(action="update", enabled=false)` before deleting it. Image member modifications require an image owned by the current project, shared visibility, and appropriate Glance policy; adding a member does not automatically accept the recipient's membership.
|
|
460
|
+
- **Logs and telemetry:** `set_service_logs(action="show")` and `set_metrics(action="show")` return explicit unsupported errors. No centralized logging or telemetry sample backend is implemented. Their list/summary operations expose service or resource metadata only.
|
|
461
|
+
|
|
444
462
|
## Quick Start
|
|
445
463
|
|
|
446
464
|
> 💡 **Need an OpenStack Cluster for Testing?**
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Integration validation
|
|
2
|
+
|
|
3
|
+
Validated on 2026-10-30 against a single-node Kolla Ansible test deployment,
|
|
4
|
+
using an administrative project. Credentials and deployment addresses are not
|
|
5
|
+
included in this report.
|
|
6
|
+
|
|
7
|
+
## Results
|
|
8
|
+
|
|
9
|
+
The final live suite recorded 68 passing checks, including prerequisite creation,
|
|
10
|
+
API read-back, asynchronous state checks, and cleanup. Three lifecycle checks
|
|
11
|
+
were skipped as described below. These counts are checks, not distinct features.
|
|
12
|
+
|
|
13
|
+
| Area | Live result |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| Connection | The project's connection factory authenticated successfully |
|
|
16
|
+
| Inventory | Domains, identity groups, backups, volume groups, volume QoS, and volume transfers were queried through actual MCP tool handlers |
|
|
17
|
+
| Monitoring and usage | Current allocation reporting and date-bounded Nova usage queries succeeded; unavailable physical capacity remained null |
|
|
18
|
+
| Floating IP pools | Allocation ranges totaled 50 addresses; one visible Floating IP was counted; global free capacity remained unknown |
|
|
19
|
+
| Routers and security groups | Created disposable resources, read them back through the SDK, deleted them through MCP tools, and confirmed absence |
|
|
20
|
+
| Volume types | Created a disposable type and removed it after group checks |
|
|
21
|
+
| Cinder QoS | Created a specification, showed it, changed its limit, verified the updated value, deleted it, and confirmed absence |
|
|
22
|
+
| Volume groups | Created a temporary group type and empty group; group reached available; show and delete succeeded |
|
|
23
|
+
| Identity | Created a disposable domain, group and user; group show/update/delete and user read-back/delete succeeded; domain was disabled and deleted during cleanup |
|
|
24
|
+
| Image sharing | Created a disposable shared image and recipient project; member add/list/remove succeeded |
|
|
25
|
+
| Heat | Created an empty stack, waited for CREATE_COMPLETE, queried resources/events/template/outputs, and deleted the stack |
|
|
26
|
+
| Backups | Created a blank 1 GiB source volume; created and showed its backup; restored into a new 1 GiB volume; waited for available states; deleted the backup and both volumes |
|
|
27
|
+
|
|
28
|
+
All registered cleanup checks passed. A final read-only audit across 14 resource
|
|
29
|
+
categories found zero remaining resources with either validation run's unique
|
|
30
|
+
names. Only disposable resources created by the validation runs were targeted
|
|
31
|
+
for deletion. Backup validation covered the API
|
|
32
|
+
lifecycle and ready states; it did not test integrity of non-empty application
|
|
33
|
+
data. Heat validation used an empty template with a constant output.
|
|
34
|
+
|
|
35
|
+
## Defect found and fixed
|
|
36
|
+
|
|
37
|
+
The existing Heat endpoint override ended at `/v1`. In the tested deployment,
|
|
38
|
+
SDK discovery failed with a `catalog_url` attribute error; forcing API version 1
|
|
39
|
+
alone instead produced a request to the invalid `/v1/stacks` path.
|
|
40
|
+
|
|
41
|
+
The connection factory now sets Heat API version 1 and, after authentication,
|
|
42
|
+
scopes the endpoint to `/v1/{project_id}`. The corrected connection passed live
|
|
43
|
+
stack creation and all four new query sections. A local regression test covers
|
|
44
|
+
the endpoint construction. The connection success log no longer includes token
|
|
45
|
+
contents.
|
|
46
|
+
|
|
47
|
+
## Limits and skipped operations
|
|
48
|
+
|
|
49
|
+
- **Network QoS:** the deployment does not advertise the Neutron `qos` extension;
|
|
50
|
+
policy listing returned HTTP 404. Successful policy creation/deletion remains
|
|
51
|
+
covered by local mocked tests, not live validation.
|
|
52
|
+
- **Alarms:** no `alarming` or `metric` service was registered in the catalog.
|
|
53
|
+
Alarm listing returned an explicit missing-endpoint failure. The successful
|
|
54
|
+
Aodh/Gnocchi lifecycle remains unverified against a live service.
|
|
55
|
+
- **Network agents:** listing succeeded. Existing cloud-wide agents were not
|
|
56
|
+
enabled or disabled to avoid affecting the platform's networking.
|
|
57
|
+
- **Logs and telemetry:** no centralized logging or telemetry sample backend
|
|
58
|
+
was added. The explicit unsupported responses remain intentional.
|
|
59
|
+
- This deployment does not establish compatibility with every OpenStack release,
|
|
60
|
+
storage backend, policy configuration, or non-administrative role.
|
|
61
|
+
|
|
62
|
+
After the Heat fix, `uv run --no-sync python -m pytest -q tests` passed all 90
|
|
63
|
+
local tests. The SDK emitted 12 deprecated-field warnings. No commit or push
|
|
64
|
+
was performed as part of validation.
|
|
@@ -7,7 +7,7 @@ requires-python = ">=3.12"
|
|
|
7
7
|
authors = [{ name = "JungJungIn", email = "call518@gmail.com" }]
|
|
8
8
|
dependencies = [
|
|
9
9
|
"fastmcp>=2.12.3",
|
|
10
|
-
"openstacksdk>=4.1.0,<=4.
|
|
10
|
+
"openstacksdk>=4.1.0,<=4.22.0",
|
|
11
11
|
"python-dotenv>=1.1.1",
|
|
12
12
|
"setuptools-scm>=10.0.5",
|
|
13
13
|
"pre-commit>=4.6.0",
|
|
@@ -109,13 +109,21 @@ def get_openstack_connection():
|
|
|
109
109
|
image_endpoint=f"{os_auth_protocol}://{os_auth_host}:{image_port}",
|
|
110
110
|
placement_endpoint=f"{os_auth_protocol}://{os_auth_host}:{placement_port}",
|
|
111
111
|
orchestration_endpoint=f"{os_auth_protocol}://{os_auth_host}:{heat_stack_port}/v1",
|
|
112
|
+
orchestration_api_version="1",
|
|
112
113
|
timeout=10
|
|
113
114
|
)
|
|
114
115
|
|
|
115
116
|
# Test the connection
|
|
116
117
|
try:
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
_connection_cache.identity.get_token()
|
|
119
|
+
# Heat URLs include the project ID, available only after authentication.
|
|
120
|
+
project_id = _connection_cache.current_project_id
|
|
121
|
+
if not project_id:
|
|
122
|
+
raise ValueError("A project-scoped OpenStack connection is required")
|
|
123
|
+
_connection_cache.config.config["orchestration_endpoint_override"] = (
|
|
124
|
+
f"{os_auth_protocol}://{os_auth_host}:{heat_stack_port}/v1/{project_id}"
|
|
125
|
+
)
|
|
126
|
+
logger.info("OpenStack connection successful")
|
|
119
127
|
except Exception as test_e:
|
|
120
128
|
logger.error(f"Connection test failed: {test_e}")
|
|
121
129
|
raise
|